Merge pull request #418 from dybvig/compress-level
Add a compress-level parameter original commit: 3ea6f8e4b166b033f1cb33293090ca78b8986db9
This commit is contained in:
commit
39c9f4d7f2
69
LOG
69
LOG
|
@ -1268,3 +1268,72 @@
|
|||
externs.h, system.h, expeditor.c, configure, Mf-*, Makefile.*nt,
|
||||
workarea, mat.ss, io.ms, io.stex, objects.stex, release_notes.stex,
|
||||
root-experr*, patch*
|
||||
- added compress-level parameter to select a compression level for
|
||||
file writing and changed the default for lz4 compression to do a
|
||||
better job compressing. finished splitting glz input routines
|
||||
apart from glz output routines and did a bit of other restructuring.
|
||||
removed gzxfile struct-as-bytevector wrapper and moved its fd
|
||||
into glzFile. moved DEACTIVATE to before glzdopen_input calls
|
||||
in S_new_open_input_fd and S_compress_input_fd, since glzdopen_input
|
||||
reads from the file and could block. the compress format and now
|
||||
level are now recorded directly the thread context. replaced
|
||||
as-gz? flag bit in compressed bytevector header word with a small
|
||||
number of bits recording the compression format at the bottom of
|
||||
the header word. flushed a couple of bytevector compression mats
|
||||
that depended on the old representation. (these last few changes
|
||||
should make adding new compression formats easier.) added
|
||||
s-directory build options to choose whether to compress and, if
|
||||
so, the format and level.
|
||||
compress-io.h, compress-io.c, new-io.c, equates.h, system.h,
|
||||
scheme.c, gc.c,
|
||||
io.ss, cmacros.ss, back.ss, bytevector.ss, primdata.ss, s/Mf-base,
|
||||
io.ms, mat.ss, bytevector.ms, root-experr*,
|
||||
release_notes.stex, io.stex, system.stex, objects.stex
|
||||
- improved the effectiveness of LZ4 boot-file compression to within
|
||||
15% of gzip by increasing the lz4 output-port in_buffer size to
|
||||
1<<18. With the previous size (1<<14) LZ4-compressed boot files
|
||||
were about 50% larger. set the lz4 input-port in_buffer and
|
||||
out_buffer sizes to 1<<12 and 1<<14. there's no clear win at
|
||||
present for larger input-port buffer sizes.
|
||||
compress-io.c
|
||||
- To reduce the memory hit for the increased output-port in_buffer
|
||||
size and the corresponding increase in computed out_buffer size,
|
||||
one output-side out_buffer is now allocated (lazily) per thread
|
||||
and stored in the thread context. The other buffers are now
|
||||
directly a part of the lz4File_out and lz4File_in structures
|
||||
rather than allocated separately.
|
||||
compress-io.c, scheme.c, gc.c,
|
||||
cmacros.ss
|
||||
- split out the buffer emit code from glzwrite_lz4 into a
|
||||
separate glzemit_lz4 helper that is now also used by gzclose
|
||||
so we can avoid dealing with a NULL buffer in glzwrite_lz4.
|
||||
glzwrite_lz4 also uses it to writing large buffers directly and
|
||||
avoid the memcpy.
|
||||
compress-io.c
|
||||
- replaced lz4File_out and lz4File_in mode enumeration with the
|
||||
compress format and inputp boolean. using switch to check and
|
||||
raising exceptions for unexpected values to further simplify
|
||||
adding new compression formats in the future.
|
||||
compress-io.c
|
||||
- replaced the never-defined struct lz4File pointer in glzFile
|
||||
union with the more specific struct lz4File_in_r and Lz4File_out_r
|
||||
pointers.
|
||||
compress-io.h, compress-io.c
|
||||
- added free of lz4 structures to gzclose. also changed file-close
|
||||
logic generally so that (1) port is marked closed before anything is
|
||||
freed to avoid dangling pointers in the case of an interrupt or
|
||||
error, and (2) structures are freed even in the case of a write
|
||||
or close error, before the error is reported. also now mallocing
|
||||
glz and lz4 structures after possibility of errors have passed where
|
||||
possible and freeing them when not.
|
||||
compress-io.c,
|
||||
io.ss
|
||||
- added return-value checks to malloc calls and to a couple of other
|
||||
C-library calls.
|
||||
compress-io.c
|
||||
- corrected EINTR checks to look at errno rather than return codes.
|
||||
compress-io.c
|
||||
- added S_ prefixes to the glz* exports
|
||||
externs.h, compress-io.c, new-io.c, scheme.c, fasl.c
|
||||
- added entries for mutex-name and mutex-thread
|
||||
threads.stex
|
||||
|
|
962
c/compress-io.c
962
c/compress-io.c
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,5 @@
|
|||
/* compress-io.h
|
||||
* Copyright 1984-2017 Cisco Systems, Inc.
|
||||
* Copyright 1984-2019 Cisco Systems, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -14,34 +14,13 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "zlib.h"
|
||||
|
||||
struct lz4File;
|
||||
|
||||
typedef struct glzFile_r {
|
||||
int mode;
|
||||
INT fd;
|
||||
IBOOL inputp;
|
||||
INT format;
|
||||
union {
|
||||
gzFile gz;
|
||||
struct lz4File *lz4;
|
||||
struct gzFile_s *gz;
|
||||
struct lz4File_in_r *lz4_in;
|
||||
struct lz4File_out_r *lz4_out;
|
||||
};
|
||||
} *glzFile;
|
||||
|
||||
glzFile glzdopen_gz(int fd, const char *mode);
|
||||
glzFile glzdopen_lz4(int fd, const char *mode);
|
||||
glzFile glzdopen(int fd, const char *mode);
|
||||
glzFile glzopen(const char *path, const char *mode);
|
||||
#ifdef WIN32
|
||||
glzFile glzopen_w(wchar_t *path, const char *mode);
|
||||
#endif
|
||||
int glzdirect(glzFile file);
|
||||
int glzclose(glzFile file);
|
||||
|
||||
int glzread(glzFile file, void *buffer, unsigned int count);
|
||||
int glzwrite(glzFile file, void *buffer, unsigned int count);
|
||||
long glzseek(glzFile file, long offset, int whence);
|
||||
int glzgetc(glzFile file);
|
||||
int glzungetc(int c, glzFile file);
|
||||
int glzrewind(glzFile file);
|
||||
|
||||
void glzerror(glzFile file, int *errnum);
|
||||
void glzclearerr(glzFile fdfile);
|
||||
|
|
31
c/externs.h
31
c/externs.h
|
@ -169,6 +169,27 @@ extern wchar_t *S_malloc_wide_pathname PROTO((const char *inpath));
|
|||
#endif
|
||||
extern IBOOL S_fixedpathp PROTO((const char *inpath));
|
||||
|
||||
/* compress-io.c */
|
||||
extern glzFile S_glzdopen_output PROTO((INT fd, INT compress_format, INT compress_level));
|
||||
extern glzFile S_glzdopen_input PROTO((INT fd));
|
||||
extern glzFile S_glzopen_input PROTO((const char *path));
|
||||
#ifdef WIN32
|
||||
extern glzFile S_glzopen_input_w PROTO((const wchar_t *path));
|
||||
#endif
|
||||
extern IBOOL S_glzdirect PROTO((glzFile file));
|
||||
extern INT S_glzclose PROTO((glzFile file));
|
||||
|
||||
extern INT S_glzread PROTO((glzFile file, void *buffer, UINT count));
|
||||
extern INT S_glzwrite PROTO((glzFile file, void *buffer, UINT count));
|
||||
extern long S_glzseek PROTO((glzFile file, long offset, INT whence));
|
||||
extern INT S_glzgetc PROTO((glzFile file));
|
||||
extern INT S_glzungetc PROTO((INT c, glzFile file));
|
||||
extern INT S_glzrewind PROTO((glzFile file));
|
||||
|
||||
extern void S_glzerror PROTO((glzFile file, INT *errnum));
|
||||
extern void S_glzclearerr PROTO((glzFile fdfile));
|
||||
|
||||
|
||||
/* new-io.c */
|
||||
extern INT S_gzxfile_fd PROTO((ptr x));
|
||||
extern glzFile S_gzxfile_gzfile PROTO((ptr x));
|
||||
|
@ -176,14 +197,14 @@ extern ptr S_new_open_input_fd PROTO((const char *filename, IBOOL compressed));
|
|||
extern ptr S_new_open_output_fd PROTO((
|
||||
const char *filename, INT mode,
|
||||
IBOOL no_create, IBOOL no_fail, IBOOL no_truncate,
|
||||
IBOOL append, IBOOL lock, IBOOL replace, IBOOL compressed, IBOOL as_gz));
|
||||
IBOOL append, IBOOL lock, IBOOL replace, IBOOL compressed));
|
||||
extern ptr S_new_open_input_output_fd PROTO((
|
||||
const char *filename, INT mode,
|
||||
IBOOL no_create, IBOOL no_fail, IBOOL no_truncate,
|
||||
IBOOL append, IBOOL lock, IBOOL replace, IBOOL compressed));
|
||||
extern ptr S_close_fd PROTO((ptr file, IBOOL gzflag));
|
||||
extern ptr S_compress_input_fd PROTO((INT fd, I64 fp));
|
||||
extern ptr S_compress_output_fd PROTO((INT fd, IBOOL as_gz));
|
||||
extern ptr S_compress_output_fd PROTO((INT fd));
|
||||
|
||||
extern ptr S_bytevector_read PROTO((ptr file, ptr buffer, iptr start, iptr count, IBOOL gzflag));
|
||||
extern ptr S_bytevector_read_nb PROTO((ptr file, ptr buffer, iptr start, iptr count, IBOOL gzflag));
|
||||
|
@ -198,13 +219,13 @@ extern ptr S_get_fd_length PROTO((ptr file, IBOOL gzflag));
|
|||
extern ptr S_set_fd_length PROTO((ptr file, ptr length, IBOOL gzflag));
|
||||
extern void S_new_io_init PROTO((void));
|
||||
|
||||
extern uptr S_bytevector_compress_size PROTO((iptr s_count, IBOOL as_gz));
|
||||
extern uptr S_bytevector_compress_size PROTO((iptr s_count, INT compress_format));
|
||||
extern ptr S_bytevector_compress PROTO((ptr dest_bv, iptr d_start, iptr d_count,
|
||||
ptr src_bv, iptr s_start, iptr s_count,
|
||||
IBOOL as_gz));
|
||||
INT compress_format));
|
||||
extern ptr S_bytevector_uncompress PROTO((ptr dest_bv, iptr d_start, iptr d_count,
|
||||
ptr src_bv, iptr s_start, iptr s_count,
|
||||
IBOOL as_gz));
|
||||
INT compress_format));
|
||||
|
||||
/* thread.c */
|
||||
extern void S_thread_init PROTO((void));
|
||||
|
|
7
c/fasl.c
7
c/fasl.c
|
@ -177,6 +177,7 @@
|
|||
*/
|
||||
|
||||
#include "system.h"
|
||||
#include "zlib.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#include <io.h>
|
||||
|
@ -346,14 +347,14 @@ static INT uf_read(unbufFaslFile uf, octet *s, iptr n) {
|
|||
|
||||
switch (uf->type) {
|
||||
case UFFO_TYPE_GZ:
|
||||
k = glzread(uf->file, s, (GZ_IO_SIZE_T)nx);
|
||||
k = S_glzread(uf->file, s, (GZ_IO_SIZE_T)nx);
|
||||
if (k > 0)
|
||||
n -= k;
|
||||
else if (k == 0)
|
||||
return -1;
|
||||
else {
|
||||
glzerror(uf->file, &errnum);
|
||||
glzclearerr(uf->file);
|
||||
S_glzerror(uf->file, &errnum);
|
||||
S_glzclearerr(uf->file);
|
||||
if (errnum != Z_ERRNO || errno != EINTR)
|
||||
S_error1("", "error reading from ~a", uf->path);
|
||||
}
|
||||
|
|
3
c/gc.c
3
c/gc.c
|
@ -1515,6 +1515,9 @@ static void sweep_thread(p) ptr p; {
|
|||
/* immediate SUPPRESSPRIMITIVEINLINING */
|
||||
relocate(&DEFAULTRECORDEQUALPROCEDURE(tc))
|
||||
relocate(&DEFAULTRECORDHASHPROCEDURE(tc))
|
||||
relocate(&COMPRESSFORMAT(tc))
|
||||
relocate(&COMPRESSLEVEL(tc))
|
||||
/* void* LZ4OUTBUFFER(tc) */
|
||||
/* U64 INSTRCOUNTER(tc) */
|
||||
/* U64 ALLOCCOUNTER(tc) */
|
||||
relocate(&PARAMETERS(tc))
|
||||
|
|
271
c/new-io.c
271
c/new-io.c
|
@ -52,9 +52,8 @@
|
|||
/* locally defined functions */
|
||||
static ptr new_open_output_fd_helper PROTO((const char *filename, INT mode,
|
||||
INT flags, INT no_create, INT no_fail, INT no_truncate,
|
||||
INT append, INT lock, INT replace, INT compressed, INT as_gz));
|
||||
INT append, INT lock, INT replace, INT compressed));
|
||||
static INT lockfile PROTO((INT fd));
|
||||
static ptr make_gzxfile PROTO((int fd, glzFile file));
|
||||
static int is_valid_zlib_length(iptr count);
|
||||
static int is_valid_lz4_length(iptr count);
|
||||
|
||||
|
@ -78,8 +77,8 @@ static int is_valid_lz4_length(iptr count);
|
|||
if (ok) { flag = 0; } \
|
||||
else { \
|
||||
INT errnum; \
|
||||
glzerror((fd),&errnum); \
|
||||
glzclearerr((fd)); \
|
||||
S_glzerror((fd),&errnum); \
|
||||
S_glzclearerr((fd)); \
|
||||
if (errnum == Z_ERRNO) { \
|
||||
flag = errno != EINTR; \
|
||||
} else { \
|
||||
|
@ -99,8 +98,8 @@ static int is_valid_lz4_length(iptr count);
|
|||
if (ok) { flag = 0; break; } \
|
||||
else { \
|
||||
INT errnum; \
|
||||
glzerror((fd),&errnum); \
|
||||
glzclearerr((fd)); \
|
||||
S_glzerror((fd),&errnum); \
|
||||
S_glzclearerr((fd)); \
|
||||
if (errnum == Z_ERRNO) { \
|
||||
if (errno != EINTR) { flag = 1; break; } \
|
||||
} else { \
|
||||
|
@ -117,8 +116,8 @@ static int is_valid_lz4_length(iptr count);
|
|||
if (ok) { flag = 0; } \
|
||||
else { \
|
||||
INT errnum; \
|
||||
glzerror((fd),&errnum); \
|
||||
glzclearerr((fd)); \
|
||||
S_glzerror((fd),&errnum); \
|
||||
S_glzclearerr((fd)); \
|
||||
if (errnum == Z_ERRNO) { flag = 1; } \
|
||||
else { \
|
||||
flag = not_ok_is_fatal || errnum != Z_OK; \
|
||||
|
@ -145,26 +144,15 @@ static INT lockfile(INT fd) { return FLOCK(fd, LOCK_EX); }
|
|||
static INT lockfile(INT fd) { return lockf(fd, F_LOCK, (off_t)0); }
|
||||
#endif
|
||||
|
||||
/* work around missing zlib API operation to extract a glzFile's fd */
|
||||
typedef struct {
|
||||
int fd;
|
||||
glzFile file;
|
||||
} gzxfile;
|
||||
#define gzxfile_fd(x) (((gzxfile *)&BVIT(x,0))->fd)
|
||||
#define gzxfile_gzfile(x) (((gzxfile *)&BVIT(x,0))->file)
|
||||
static ptr make_gzxfile(int fd, glzFile file) {
|
||||
ptr bv;
|
||||
#define MAKE_GZXFILE(x) Sinteger((iptr)x)
|
||||
#define GZXFILE_GZFILE(x) ((glzFile)Sinteger_value(x))
|
||||
|
||||
bv = S_bytevector(sizeof(gzxfile));
|
||||
gzxfile_fd(bv) = fd;
|
||||
gzxfile_gzfile(bv) = file;
|
||||
return bv;
|
||||
}
|
||||
INT S_gzxfile_fd(ptr x) {
|
||||
return gzxfile_fd(x);
|
||||
return GZXFILE_GZFILE(x)->fd;
|
||||
}
|
||||
|
||||
glzFile S_gzxfile_gzfile(ptr x) {
|
||||
return gzxfile_gzfile(x);
|
||||
return GZXFILE_GZFILE(x);
|
||||
}
|
||||
|
||||
ptr S_new_open_input_fd(const char *infilename, IBOOL compressed) {
|
||||
|
@ -209,25 +197,26 @@ ptr S_new_open_input_fd(const char *infilename, IBOOL compressed) {
|
|||
return Scons(FIX(OPEN_ERROR_OTHER), str);
|
||||
}
|
||||
|
||||
if ((file = glzdopen(dupfd, "rb")) == Z_NULL) {
|
||||
DEACTIVATE(tc) /* glzdopen_input reads the magic word from the file */
|
||||
if ((file = S_glzdopen_input(dupfd)) == Z_NULL) {
|
||||
REACTIVATE(tc)
|
||||
FD_GUARD(result == 0, error, result = CLOSE(fd));
|
||||
FD_GUARD(result == 0, error, result = CLOSE(dupfd));
|
||||
return Scons(FIX(OPEN_ERROR_OTHER), Sstring("unable to allocate compression state (too many open files?)"));
|
||||
}
|
||||
|
||||
DEACTIVATE(tc)
|
||||
compressed = !glzdirect(file);
|
||||
compressed = !S_glzdirect(file);
|
||||
REACTIVATE(tc)
|
||||
|
||||
if (compressed) {
|
||||
FD_GUARD(result == 0, error, result = CLOSE(fd));
|
||||
/* box indicates gzip'd */
|
||||
return Sbox(make_gzxfile(dupfd, file));
|
||||
/* box indicates compressed */
|
||||
return Sbox(MAKE_GZXFILE(file));
|
||||
}
|
||||
|
||||
GZ_GUARD(1, ok == 0 || ok == Z_BUF_ERROR, flag, file, ok = glzclose(file));
|
||||
GZ_GUARD(1, ok == 0 || ok == Z_BUF_ERROR, flag, file, ok = S_glzclose(file));
|
||||
if (flag) {} /* make the compiler happy */
|
||||
if (LSEEK(fd, 0, SEEK_SET) != 0) { /* glzdirect does not leave fd at position 0 */
|
||||
if (LSEEK(fd, 0, SEEK_SET) != 0) { /* glzdopen and glzdirect might not leave fd at position 0 */
|
||||
FD_GUARD(result == 0, error, result = CLOSE(fd));
|
||||
return Scons(FIX(OPEN_ERROR_OTHER),Sstring("unable to reset after reading header bytes"));
|
||||
}
|
||||
|
@ -245,22 +234,24 @@ ptr S_compress_input_fd(INT fd, I64 pos) {
|
|||
return S_strerror(errno);
|
||||
}
|
||||
|
||||
if ((file = glzdopen(dupfd, "rb")) == Z_NULL) {
|
||||
DEACTIVATE(tc)
|
||||
if ((file = S_glzdopen_input(dupfd)) == Z_NULL) {
|
||||
REACTIVATE(tc)
|
||||
FD_GUARD(result == 0, error, result = CLOSE(dupfd));
|
||||
return Sstring("unable to allocate compression state (too many open files?)");
|
||||
}
|
||||
|
||||
DEACTIVATE(tc)
|
||||
compressed = !glzdirect(file);
|
||||
compressed = !S_glzdirect(file);
|
||||
REACTIVATE(tc)
|
||||
|
||||
if (compressed) {
|
||||
FD_GUARD(result == 0, error, result = CLOSE(fd));
|
||||
if (error) {} /* make the compiler happy */
|
||||
return Sbox(make_gzxfile(dupfd, file));
|
||||
/* box indicates compressed */
|
||||
return Sbox(MAKE_GZXFILE(file));
|
||||
}
|
||||
|
||||
GZ_GUARD(1, ok == 0 || ok == Z_BUF_ERROR, flag, file, ok = glzclose(file));
|
||||
GZ_GUARD(1, ok == 0 || ok == Z_BUF_ERROR, flag, file, ok = S_glzclose(file));
|
||||
if (flag) {} /* make the compiler happy */
|
||||
if (LSEEK(fd, pos, SEEK_SET) != pos) { /* glzdirect does not leave fd at same position */
|
||||
return Sstring("unable to reset after reading header bytes");
|
||||
|
@ -268,38 +259,28 @@ ptr S_compress_input_fd(INT fd, I64 pos) {
|
|||
return MAKE_FD(fd);
|
||||
}
|
||||
|
||||
ptr S_compress_output_fd(INT fd, IBOOL as_gz) {
|
||||
ptr S_compress_output_fd(INT fd) {
|
||||
glzFile file;
|
||||
int as_append;
|
||||
ptr tc = get_thread_context();
|
||||
|
||||
#ifdef WIN32
|
||||
as_append = 0;
|
||||
#else
|
||||
as_append = fcntl(fd, F_GETFL) & O_APPEND;
|
||||
#endif
|
||||
|
||||
if (as_gz)
|
||||
file = glzdopen_gz(fd, as_append ? "ab" : "wb");
|
||||
else
|
||||
file = glzdopen_lz4(fd, as_append ? "ab" : "wb");
|
||||
file = S_glzdopen_output(fd, (INT)UNFIX(COMPRESSFORMAT(tc)), (INT)UNFIX(COMPRESSLEVEL(tc)));
|
||||
|
||||
if (file == Z_NULL)
|
||||
return Sstring("unable to allocate compression state (too many open files?)");
|
||||
|
||||
return Sbox(make_gzxfile(fd, file));
|
||||
/* box indicates compressed */
|
||||
return Sbox(MAKE_GZXFILE(file));
|
||||
}
|
||||
|
||||
static ptr new_open_output_fd_helper(
|
||||
const char *infilename, INT mode, INT flags,
|
||||
IBOOL no_create, IBOOL no_fail, IBOOL no_truncate,
|
||||
IBOOL append, IBOOL lock, IBOOL replace, IBOOL compressed, IBOOL as_gz) {
|
||||
IBOOL append, IBOOL lock, IBOOL replace, IBOOL compressed) {
|
||||
char *filename;
|
||||
INT saved_errno = 0;
|
||||
iptr error;
|
||||
INT fd, result;
|
||||
#ifdef PTHREADS
|
||||
ptr tc = get_thread_context();
|
||||
#endif
|
||||
|
||||
flags |=
|
||||
(no_create ? 0 : O_CREAT) |
|
||||
|
@ -358,26 +339,23 @@ static ptr new_open_output_fd_helper(
|
|||
}
|
||||
|
||||
glzFile file;
|
||||
if (as_gz)
|
||||
file = glzdopen_gz(fd, append ? "ab" : "wb");
|
||||
else
|
||||
file = glzdopen_lz4(fd, append ? "ab" : "wb");
|
||||
file = S_glzdopen_output(fd, (INT)UNFIX(COMPRESSFORMAT(tc)), (INT)UNFIX(COMPRESSLEVEL(tc)));
|
||||
if (file == Z_NULL) {
|
||||
FD_GUARD(result == 0, error, result = CLOSE(fd));
|
||||
return Scons(FIX(OPEN_ERROR_OTHER), Sstring("unable to allocate compression state"));
|
||||
}
|
||||
|
||||
return make_gzxfile(fd, file);
|
||||
return MAKE_GZXFILE(file);
|
||||
}
|
||||
|
||||
ptr S_new_open_output_fd(
|
||||
const char *filename, INT mode,
|
||||
IBOOL no_create, IBOOL no_fail, IBOOL no_truncate,
|
||||
IBOOL append, IBOOL lock, IBOOL replace, IBOOL compressed, IBOOL as_gz) {
|
||||
IBOOL append, IBOOL lock, IBOOL replace, IBOOL compressed) {
|
||||
return new_open_output_fd_helper(
|
||||
filename, mode, O_BINARY | O_WRONLY,
|
||||
no_create, no_fail, no_truncate,
|
||||
append, lock, replace, compressed, as_gz);
|
||||
append, lock, replace, compressed);
|
||||
}
|
||||
|
||||
ptr S_new_open_input_output_fd(
|
||||
|
@ -390,14 +368,14 @@ ptr S_new_open_input_output_fd(
|
|||
return new_open_output_fd_helper(
|
||||
filename, mode, O_BINARY | O_RDWR,
|
||||
no_create, no_fail, no_truncate,
|
||||
append, lock, replace, compressed, 0);
|
||||
append, lock, replace, 0);
|
||||
}
|
||||
|
||||
ptr S_close_fd(ptr file, IBOOL gzflag) {
|
||||
INT saved_errno = 0;
|
||||
INT ok, flag;
|
||||
INT fd = gzflag ? 0 : GET_FD(file);
|
||||
glzFile gzfile = gzflag ? gzxfile_gzfile(file) : NULL;
|
||||
glzFile gzfile = gzflag ? GZXFILE_GZFILE(file) : NULL;
|
||||
#ifdef PTHREADS
|
||||
ptr tc = get_thread_context();
|
||||
#endif
|
||||
|
@ -414,7 +392,7 @@ ptr S_close_fd(ptr file, IBOOL gzflag) {
|
|||
FD_GUARD(ok == 0, flag, ok = CLOSE(fd));
|
||||
} else {
|
||||
/* zlib 1.2.1 returns Z_BUF_ERROR when closing an empty file opened for reading */
|
||||
GZ_GUARD(1, ok == 0 || ok == Z_BUF_ERROR, flag, gzfile, ok = glzclose(gzfile));
|
||||
GZ_GUARD(1, ok == 0 || ok == Z_BUF_ERROR, flag, gzfile, ok = S_glzclose(gzfile));
|
||||
}
|
||||
saved_errno = errno;
|
||||
REACTIVATE(tc)
|
||||
|
@ -444,7 +422,7 @@ ptr S_bytevector_read(ptr file, ptr bv, iptr start, iptr count, IBOOL gzflag) {
|
|||
ptr tc = get_thread_context();
|
||||
iptr m, flag = 0;
|
||||
INT fd = gzflag ? 0 : GET_FD(file);
|
||||
glzFile gzfile = gzflag ? gzxfile_gzfile(file) : NULL;
|
||||
glzFile gzfile = gzflag ? GZXFILE_GZFILE(file) : NULL;
|
||||
|
||||
/* file is not locked; do not reference after deactivating thread! */
|
||||
file = (ptr)-1;
|
||||
|
@ -477,7 +455,7 @@ ptr S_bytevector_read(ptr file, ptr bv, iptr start, iptr count, IBOOL gzflag) {
|
|||
GZ_EINTR_GUARD(
|
||||
1, m >= 0 || Sboolean_value(KEYBOARDINTERRUPTPENDING(tc)),
|
||||
flag, gzfile,
|
||||
m = glzread(gzfile, &BVIT(bv,start), (GZ_IO_SIZE_T)count));
|
||||
m = S_glzread(gzfile, &BVIT(bv,start), (GZ_IO_SIZE_T)count));
|
||||
}
|
||||
}
|
||||
saved_errno = errno;
|
||||
|
@ -561,7 +539,7 @@ ptr S_bytevector_write(ptr file, ptr bv, iptr start, iptr count, IBOOL gzflag) {
|
|||
ptr tc = get_thread_context();
|
||||
INT flag = 0, saved_errno = 0;
|
||||
INT fd = gzflag ? 0 : GET_FD(file);
|
||||
glzFile gzfile = gzflag ? gzxfile_gzfile(file) : NULL;
|
||||
glzFile gzfile = gzflag ? GZXFILE_GZFILE(file) : NULL;
|
||||
|
||||
for (s = start, c = count; c > 0; s += i, c -= i) {
|
||||
iptr cx = c;
|
||||
|
@ -579,7 +557,7 @@ ptr S_bytevector_write(ptr file, ptr bv, iptr start, iptr count, IBOOL gzflag) {
|
|||
GZ_EINTR_GUARD(
|
||||
i < 0, i > 0 || Sboolean_value(KEYBOARDINTERRUPTPENDING(tc)),
|
||||
flag, gzfile,
|
||||
i = glzwrite(gzfile, &BVIT(bv,s), (GZ_IO_SIZE_T)cx));
|
||||
i = S_glzwrite(gzfile, &BVIT(bv,s), (GZ_IO_SIZE_T)cx));
|
||||
} else {
|
||||
FD_EINTR_GUARD(i >= 0 || Sboolean_value(KEYBOARDINTERRUPTPENDING(tc)),
|
||||
flag, i = WRITE(fd, &BVIT(bv,s), (IO_SIZE_T)cx));
|
||||
|
@ -623,7 +601,7 @@ ptr S_put_byte(ptr file, INT byte, IBOOL gzflag) {
|
|||
ptr tc = get_thread_context();
|
||||
INT flag = 0, saved_errno = 0;
|
||||
INT fd = gzflag ? 0 : GET_FD(file);
|
||||
glzFile gzfile = gzflag ? gzxfile_gzfile(file) : NULL;
|
||||
glzFile gzfile = gzflag ? GZXFILE_GZFILE(file) : NULL;
|
||||
octet buf[1];
|
||||
|
||||
buf[0] = (octet)byte;
|
||||
|
@ -634,7 +612,7 @@ ptr S_put_byte(ptr file, INT byte, IBOOL gzflag) {
|
|||
GZ_EINTR_GUARD(
|
||||
i < 0, i > 0 || Sboolean_value(KEYBOARDINTERRUPTPENDING(tc)),
|
||||
flag, gzfile,
|
||||
i = glzwrite(gzfile, buf, 1));
|
||||
i = S_glzwrite(gzfile, buf, 1));
|
||||
} else {
|
||||
FD_EINTR_GUARD(i >= 0 || Sboolean_value(KEYBOARDINTERRUPTPENDING(tc)),
|
||||
flag, i = WRITE(fd, buf, 1));
|
||||
|
@ -664,7 +642,7 @@ ptr S_put_byte(ptr file, INT byte, IBOOL gzflag) {
|
|||
ptr S_get_fd_pos(ptr file, IBOOL gzflag) {
|
||||
errno = 0;
|
||||
if (gzflag) {
|
||||
z_off_t offset = glzseek(gzxfile_gzfile(file), 0, SEEK_CUR);
|
||||
z_off_t offset = S_glzseek(GZXFILE_GZFILE(file), 0, SEEK_CUR);
|
||||
if (offset != -1) return Sinteger64(offset);
|
||||
} else {
|
||||
OFF_T offset = LSEEK(GET_FD(file), 0, SEEK_CUR);
|
||||
|
@ -683,7 +661,7 @@ ptr S_set_fd_pos(ptr file, ptr pos, IBOOL gzflag) {
|
|||
if (sizeof(z_off_t) != sizeof(I64))
|
||||
if (offset != offset64) return Sstring("invalid position");
|
||||
errno = 0;
|
||||
if (glzseek(gzxfile_gzfile(file),offset,SEEK_SET) == offset) return Strue;
|
||||
if (S_glzseek(GZXFILE_GZFILE(file),offset,SEEK_SET) == offset) return Strue;
|
||||
if (errno == 0) return Sstring("compression failed");
|
||||
return S_strerror(errno);
|
||||
} else {
|
||||
|
@ -811,96 +789,115 @@ static int is_valid_lz4_length(iptr len) {
|
|||
/* Accept `iptr` because we expect it to represent a bytevector size,
|
||||
which always fits in `iptr`. Return `uptr`, because the result might
|
||||
not fit in `iptr`. */
|
||||
uptr S_bytevector_compress_size(iptr s_count, IBOOL as_gz) {
|
||||
if (as_gz) {
|
||||
if (is_valid_zlib_length(s_count))
|
||||
return compressBound((uLong)s_count);
|
||||
else {
|
||||
/* Compression will report "source too long" */
|
||||
uptr S_bytevector_compress_size(iptr s_count, INT compress_format) {
|
||||
switch (compress_format) {
|
||||
case COMPRESS_GZIP:
|
||||
if (is_valid_zlib_length(s_count))
|
||||
return compressBound((uLong)s_count);
|
||||
else {
|
||||
/* Compression will report "source too long" */
|
||||
return 0;
|
||||
}
|
||||
case COMPRESS_LZ4:
|
||||
if (is_valid_lz4_length(s_count))
|
||||
return LZ4_compressBound((uLong)s_count);
|
||||
else {
|
||||
/* Compression will report "source too long" */
|
||||
return 0;
|
||||
}
|
||||
default:
|
||||
S_error1("S_bytevector_compress_size", "unexpected compress format ~s", FIX(compress_format));
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (is_valid_lz4_length(s_count))
|
||||
return LZ4_compressBound((uLong)s_count);
|
||||
else {
|
||||
/* Compression will report "source too long" */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ptr S_bytevector_compress(ptr dest_bv, iptr d_start, iptr d_count,
|
||||
ptr src_bv, iptr s_start, iptr s_count,
|
||||
IBOOL as_gz) {
|
||||
INT compress_format) {
|
||||
/* On error, an message-template string with ~s for the bytevector */
|
||||
if (as_gz) {
|
||||
int r;
|
||||
uLong destLen;
|
||||
|
||||
if (!is_valid_zlib_length(s_count))
|
||||
return Sstring("source bytevector ~s is too large");
|
||||
|
||||
destLen = (uLong)d_count;
|
||||
|
||||
r = compress(&BVIT(dest_bv, d_start), &destLen, &BVIT(src_bv, s_start), (uLong)s_count);
|
||||
|
||||
if (r == Z_OK)
|
||||
return FIX(destLen);
|
||||
else if (r == Z_BUF_ERROR)
|
||||
return Sstring("destination bytevector is too small for compressed form of ~s");
|
||||
else
|
||||
return Sstring("internal error compressing ~s");
|
||||
} else {
|
||||
int destLen;
|
||||
switch (compress_format) {
|
||||
case COMPRESS_GZIP:
|
||||
{
|
||||
int r;
|
||||
uLong destLen;
|
||||
|
||||
if (!is_valid_lz4_length(s_count))
|
||||
return Sstring("source bytevector ~s is too large");
|
||||
if (!is_valid_zlib_length(s_count))
|
||||
return Sstring("source bytevector ~s is too large");
|
||||
|
||||
destLen = (int)d_count;
|
||||
destLen = (uLong)d_count;
|
||||
|
||||
destLen = LZ4_compress_default((char *)&BVIT(src_bv, s_start), (char *)&BVIT(dest_bv, d_start), (int)s_count, (int)d_count);
|
||||
r = compress(&BVIT(dest_bv, d_start), &destLen, &BVIT(src_bv, s_start), (uLong)s_count);
|
||||
|
||||
if (destLen > 0)
|
||||
return Sfixnum(destLen);
|
||||
else
|
||||
return Sstring("compression failed for ~s");
|
||||
if (r == Z_OK)
|
||||
return FIX(destLen);
|
||||
else if (r == Z_BUF_ERROR)
|
||||
return Sstring("destination bytevector is too small for compressed form of ~s");
|
||||
else
|
||||
return Sstring("internal error compressing ~s");
|
||||
}
|
||||
case COMPRESS_LZ4:
|
||||
{
|
||||
int destLen;
|
||||
|
||||
if (!is_valid_lz4_length(s_count))
|
||||
return Sstring("source bytevector ~s is too large");
|
||||
|
||||
destLen = (int)d_count;
|
||||
|
||||
destLen = LZ4_compress_default((char *)&BVIT(src_bv, s_start), (char *)&BVIT(dest_bv, d_start), (int)s_count, (int)d_count);
|
||||
|
||||
if (destLen > 0)
|
||||
return Sfixnum(destLen);
|
||||
else
|
||||
return Sstring("compression failed for ~s");
|
||||
}
|
||||
default:
|
||||
S_error1("S_bytevector_compress", "unexpected compress format ~s", FIX(compress_format));
|
||||
return Sfalse;
|
||||
}
|
||||
}
|
||||
|
||||
ptr S_bytevector_uncompress(ptr dest_bv, iptr d_start, iptr d_count,
|
||||
ptr src_bv, iptr s_start, iptr s_count,
|
||||
IBOOL as_gz) {
|
||||
INT compress_format) {
|
||||
/* On error, an message-template string with ~s for the bytevector */
|
||||
if (as_gz) {
|
||||
int r;
|
||||
uLongf destLen;
|
||||
switch (compress_format) {
|
||||
case COMPRESS_GZIP:
|
||||
{
|
||||
int r;
|
||||
uLongf destLen;
|
||||
|
||||
if (!is_valid_zlib_length(d_count))
|
||||
return Sstring("expected result size of uncompressed source ~s is too large");
|
||||
if (!is_valid_zlib_length(d_count))
|
||||
return Sstring("expected result size of uncompressed source ~s is too large");
|
||||
|
||||
destLen = (uLongf)d_count;
|
||||
destLen = (uLongf)d_count;
|
||||
|
||||
r = uncompress(&BVIT(dest_bv, d_start), &destLen, &BVIT(src_bv, s_start), (uLong)s_count);
|
||||
r = uncompress(&BVIT(dest_bv, d_start), &destLen, &BVIT(src_bv, s_start), (uLong)s_count);
|
||||
|
||||
if (r == Z_OK)
|
||||
return FIX(destLen);
|
||||
else if (r == Z_BUF_ERROR)
|
||||
return Sstring("uncompressed ~s is larger than expected size");
|
||||
else if (r == Z_DATA_ERROR)
|
||||
return Sstring("invalid data in source bytevector ~s");
|
||||
else
|
||||
return Sstring("internal error uncompressing ~s");
|
||||
} else {
|
||||
int r;
|
||||
if (r == Z_OK)
|
||||
return FIX(destLen);
|
||||
else if (r == Z_BUF_ERROR)
|
||||
return Sstring("uncompressed ~s is larger than expected size");
|
||||
else if (r == Z_DATA_ERROR)
|
||||
return Sstring("invalid data in source bytevector ~s");
|
||||
else
|
||||
return Sstring("internal error uncompressing ~s");
|
||||
}
|
||||
case COMPRESS_LZ4:
|
||||
{
|
||||
int r;
|
||||
|
||||
if (!is_valid_lz4_length(d_count))
|
||||
return Sstring("expected result size of uncompressed source ~s is too large");
|
||||
if (!is_valid_lz4_length(d_count))
|
||||
return Sstring("expected result size of uncompressed source ~s is too large");
|
||||
|
||||
r = LZ4_decompress_safe((char *)&BVIT(src_bv, s_start), (char *)&BVIT(dest_bv, d_start), (int)s_count, (int)d_count);
|
||||
r = LZ4_decompress_safe((char *)&BVIT(src_bv, s_start), (char *)&BVIT(dest_bv, d_start), (int)s_count, (int)d_count);
|
||||
|
||||
if (r >= 0)
|
||||
return Sfixnum(r);
|
||||
else
|
||||
return Sstring("internal error uncompressing ~s");
|
||||
if (r >= 0)
|
||||
return Sfixnum(r);
|
||||
else
|
||||
return Sstring("internal error uncompressing ~s");
|
||||
}
|
||||
default:
|
||||
return Sstring("unepxected compress format ~s");
|
||||
}
|
||||
}
|
||||
|
|
106
c/scheme.c
106
c/scheme.c
|
@ -585,17 +585,17 @@ static IBOOL find_boot(name, ext, fd, errorp) const char *name, *ext; int fd; IB
|
|||
path = name;
|
||||
|
||||
if (fd != -1) {
|
||||
file = glzdopen(fd, "rb");
|
||||
file = S_glzdopen_input(fd);
|
||||
} else {
|
||||
#ifdef WIN32
|
||||
expandedpath = S_malloc_wide_pathname(path);
|
||||
file = glzopen_w(expandedpath, "rb");
|
||||
file = S_glzopen_input_w(expandedpath);
|
||||
#else
|
||||
expandedpath = S_malloc_pathname(path);
|
||||
file = glzopen(expandedpath, "rb");
|
||||
file = S_glzopen_input(expandedpath);
|
||||
#endif
|
||||
/* assumption (seemingly true based on a glance at the source code):
|
||||
glzopen doesn't squirrel away a pointer to expandedpath. */
|
||||
S_glzopen_input doesn't squirrel away a pointer to expandedpath. */
|
||||
free(expandedpath);
|
||||
}
|
||||
|
||||
|
@ -611,14 +611,14 @@ static IBOOL find_boot(name, ext, fd, errorp) const char *name, *ext; int fd; IB
|
|||
if (verbose) fprintf(stderr, "trying %s...opened\n", path);
|
||||
|
||||
/* check for magic number */
|
||||
if (glzgetc(file) != fasl_type_header ||
|
||||
glzgetc(file) != 0 ||
|
||||
glzgetc(file) != 0 ||
|
||||
glzgetc(file) != 0 ||
|
||||
glzgetc(file) != 'c' ||
|
||||
glzgetc(file) != 'h' ||
|
||||
glzgetc(file) != 'e' ||
|
||||
glzgetc(file) != 'z') {
|
||||
if (S_glzgetc(file) != fasl_type_header ||
|
||||
S_glzgetc(file) != 0 ||
|
||||
S_glzgetc(file) != 0 ||
|
||||
S_glzgetc(file) != 0 ||
|
||||
S_glzgetc(file) != 'c' ||
|
||||
S_glzgetc(file) != 'h' ||
|
||||
S_glzgetc(file) != 'e' ||
|
||||
S_glzgetc(file) != 'z') {
|
||||
fprintf(stderr, "malformed fasl-object header in %s\n", path);
|
||||
S_abnormal_exit();
|
||||
}
|
||||
|
@ -626,7 +626,7 @@ static IBOOL find_boot(name, ext, fd, errorp) const char *name, *ext; int fd; IB
|
|||
/* check version */
|
||||
if (zget_uptr(file, &n) != 0) {
|
||||
fprintf(stderr, "unexpected end of file on %s\n", path);
|
||||
glzclose(file);
|
||||
S_glzclose(file);
|
||||
S_abnormal_exit();
|
||||
}
|
||||
|
||||
|
@ -634,21 +634,21 @@ static IBOOL find_boot(name, ext, fd, errorp) const char *name, *ext; int fd; IB
|
|||
fprintf(stderr, "%s is for Version %s; ", path, S_format_scheme_version(n));
|
||||
/* use separate fprintf since S_format_scheme_version returns static string */
|
||||
fprintf(stderr, "need Version %s\n", S_format_scheme_version(scheme_version));
|
||||
glzclose(file);
|
||||
S_glzclose(file);
|
||||
S_abnormal_exit();
|
||||
}
|
||||
|
||||
/* check machine type */
|
||||
if (zget_uptr(file, &n) != 0) {
|
||||
fprintf(stderr, "unexpected end of file on %s\n", path);
|
||||
glzclose(file);
|
||||
S_glzclose(file);
|
||||
S_abnormal_exit();
|
||||
}
|
||||
|
||||
if (n != machine_type) {
|
||||
fprintf(stderr, "%s is for machine-type %s; need machine-type %s\n", path,
|
||||
S_lookup_machine_type(n), S_lookup_machine_type(machine_type));
|
||||
glzclose(file);
|
||||
S_glzclose(file);
|
||||
S_abnormal_exit();
|
||||
}
|
||||
} else {
|
||||
|
@ -671,13 +671,13 @@ static IBOOL find_boot(name, ext, fd, errorp) const char *name, *ext; int fd; IB
|
|||
|
||||
#ifdef WIN32
|
||||
expandedpath = S_malloc_wide_pathname(path);
|
||||
file = glzopen_w(expandedpath, "rb");
|
||||
file = S_glzopen_input_w(expandedpath);
|
||||
#else
|
||||
expandedpath = S_malloc_pathname(path);
|
||||
file = glzopen(expandedpath, "rb");
|
||||
file = S_glzopen_input(expandedpath);
|
||||
#endif
|
||||
/* assumption (seemingly true based on a glance at the source code):
|
||||
glzopen doesn't squirrel away a pointer to expandedpath. */
|
||||
S_glzopen_input doesn't squirrel away a pointer to expandedpath. */
|
||||
free(expandedpath);
|
||||
if (!file) {
|
||||
if (verbose) fprintf(stderr, "trying %s...cannot open\n", path);
|
||||
|
@ -687,23 +687,23 @@ static IBOOL find_boot(name, ext, fd, errorp) const char *name, *ext; int fd; IB
|
|||
if (verbose) fprintf(stderr, "trying %s...opened\n", path);
|
||||
|
||||
/* check for magic number */
|
||||
if (glzgetc(file) != fasl_type_header ||
|
||||
glzgetc(file) != 0 ||
|
||||
glzgetc(file) != 0 ||
|
||||
glzgetc(file) != 0 ||
|
||||
glzgetc(file) != 'c' ||
|
||||
glzgetc(file) != 'h' ||
|
||||
glzgetc(file) != 'e' ||
|
||||
glzgetc(file) != 'z') {
|
||||
if (S_glzgetc(file) != fasl_type_header ||
|
||||
S_glzgetc(file) != 0 ||
|
||||
S_glzgetc(file) != 0 ||
|
||||
S_glzgetc(file) != 0 ||
|
||||
S_glzgetc(file) != 'c' ||
|
||||
S_glzgetc(file) != 'h' ||
|
||||
S_glzgetc(file) != 'e' ||
|
||||
S_glzgetc(file) != 'z') {
|
||||
if (verbose) fprintf(stderr, "malformed fasl-object header in %s\n", path);
|
||||
glzclose(file);
|
||||
S_glzclose(file);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* check version */
|
||||
if (zget_uptr(file, &n) != 0) {
|
||||
if (verbose) fprintf(stderr, "unexpected end of file on %s\n", path);
|
||||
glzclose(file);
|
||||
S_glzclose(file);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -713,14 +713,14 @@ static IBOOL find_boot(name, ext, fd, errorp) const char *name, *ext; int fd; IB
|
|||
/* use separate fprintf since S_format_scheme_version returns static string */
|
||||
fprintf(stderr, "need Version %s\n", S_format_scheme_version(scheme_version));
|
||||
}
|
||||
glzclose(file);
|
||||
S_glzclose(file);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* check machine type */
|
||||
if (zget_uptr(file, &n) != 0) {
|
||||
if (verbose) fprintf(stderr, "unexpected end of file on %s\n", path);
|
||||
glzclose(file);
|
||||
S_glzclose(file);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -728,7 +728,7 @@ static IBOOL find_boot(name, ext, fd, errorp) const char *name, *ext; int fd; IB
|
|||
if (verbose)
|
||||
fprintf(stderr, "%s is for machine-type %s; need machine-type %s\n", path,
|
||||
S_lookup_machine_type(n), S_lookup_machine_type(machine_type));
|
||||
glzclose(file);
|
||||
S_glzclose(file);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -738,56 +738,56 @@ static IBOOL find_boot(name, ext, fd, errorp) const char *name, *ext; int fd; IB
|
|||
|
||||
if (verbose) fprintf(stderr, "version and machine type check\n");
|
||||
|
||||
if (glzgetc(file) != '(') { /* ) */
|
||||
if (S_glzgetc(file) != '(') { /* ) */
|
||||
fprintf(stderr, "malformed boot file %s\n", path);
|
||||
glzclose(file);
|
||||
S_glzclose(file);
|
||||
S_abnormal_exit();
|
||||
}
|
||||
|
||||
/* ( */
|
||||
if ((c = glzgetc(file)) == ')') {
|
||||
if ((c = S_glzgetc(file)) == ')') {
|
||||
if (boot_count != 0) {
|
||||
fprintf(stderr, "base boot file %s must come before other boot files\n", path);
|
||||
glzclose(file);
|
||||
S_glzclose(file);
|
||||
S_abnormal_exit();
|
||||
}
|
||||
} else {
|
||||
if (boot_count == 0) {
|
||||
for (;;) {
|
||||
glzungetc(c, file);
|
||||
S_glzungetc(c, file);
|
||||
/* try to load heap or boot file this boot file requires */
|
||||
if (zgetstr(file, buf, PATH_MAX) != 0) {
|
||||
fprintf(stderr, "unexpected end of file on %s\n", path);
|
||||
glzclose(file);
|
||||
S_glzclose(file);
|
||||
S_abnormal_exit();
|
||||
}
|
||||
if (find_boot(buf, ".boot", -1, 0)) break;
|
||||
if ((c = glzgetc(file)) == ')') {
|
||||
if ((c = S_glzgetc(file)) == ')') {
|
||||
char *sep; char *wastebuf[8];
|
||||
fprintf(stderr, "cannot find subordinate boot file ");
|
||||
glzrewind(file);
|
||||
(void) glzread(file, wastebuf, 8); /* magic number */
|
||||
S_glzrewind(file);
|
||||
(void) S_glzread(file, wastebuf, 8); /* magic number */
|
||||
(void) zget_uptr(file, &n); /* version */
|
||||
(void) zget_uptr(file, &n); /* machine type */
|
||||
(void) glzgetc(file); /* open paren */
|
||||
(void) S_glzgetc(file); /* open paren */
|
||||
for (sep = ""; ; sep = "or ") {
|
||||
if ((c = glzgetc(file)) == ')') break;
|
||||
glzungetc(c, file);
|
||||
if ((c = S_glzgetc(file)) == ')') break;
|
||||
S_glzungetc(c, file);
|
||||
(void) zgetstr(file, buf, PATH_MAX);
|
||||
fprintf(stderr, "%s%s.boot ", sep, buf);
|
||||
}
|
||||
fprintf(stderr, "required by %s\n", path);
|
||||
glzclose(file);
|
||||
S_glzclose(file);
|
||||
S_abnormal_exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* skip to end of header */
|
||||
while ((c = glzgetc(file)) != ')') {
|
||||
while ((c = S_glzgetc(file)) != ')') {
|
||||
if (c < 0) {
|
||||
fprintf(stderr, "malformed boot file %s\n", path);
|
||||
glzclose(file);
|
||||
S_glzclose(file);
|
||||
S_abnormal_exit();
|
||||
}
|
||||
}
|
||||
|
@ -808,11 +808,11 @@ static IBOOL find_boot(name, ext, fd, errorp) const char *name, *ext; int fd; IB
|
|||
static uptr zget_uptr(glzFile file, uptr *pn) {
|
||||
uptr n, m; int c; octet k;
|
||||
|
||||
if ((c = glzgetc(file)) < 0) return -1;
|
||||
if ((c = S_glzgetc(file)) < 0) return -1;
|
||||
k = (octet)c;
|
||||
n = k >> 1;
|
||||
while (k & 1) {
|
||||
if ((c = glzgetc(file)) < 0) return -1;
|
||||
if ((c = S_glzgetc(file)) < 0) return -1;
|
||||
k = (octet)c;
|
||||
m = n << 7;
|
||||
if (m >> 7 != n) return -1;
|
||||
|
@ -826,9 +826,9 @@ static INT zgetstr(file, s, max) glzFile file; char *s; iptr max; {
|
|||
ICHAR c;
|
||||
|
||||
while (max-- > 0) {
|
||||
if ((c = glzgetc(file)) < 0) return -1;
|
||||
if ((c = S_glzgetc(file)) < 0) return -1;
|
||||
if (c == ' ' || c == ')') {
|
||||
if (c == ')') glzungetc(c, file);
|
||||
if (c == ')') S_glzungetc(c, file);
|
||||
*s = 0;
|
||||
return 0;
|
||||
}
|
||||
|
@ -923,7 +923,7 @@ static void load(tc, n, base) ptr tc; iptr n; IBOOL base; {
|
|||
}
|
||||
|
||||
S_G.load_binary = Sfalse;
|
||||
glzclose(bd[n].file);
|
||||
S_glzclose(bd[n].file);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
@ -1137,6 +1137,8 @@ extern void Sbuild_heap(kernel, custom_init) const char *kernel; void (*custom_i
|
|||
/* #scheme-init enables interrupts */
|
||||
TRAP(tc) = (ptr)most_positive_fixnum;
|
||||
DISABLECOUNT(tc) = Sfixnum(1);
|
||||
COMPRESSFORMAT(tc) = FIX(COMPRESS_LZ4);
|
||||
COMPRESSLEVEL(tc) = FIX(COMPRESS_MEDIUM);
|
||||
|
||||
load(tc, i++, 1);
|
||||
S_boot_time = 0;
|
||||
|
|
|
@ -24,13 +24,14 @@
|
|||
|
||||
#include "version.h"
|
||||
#include <stdio.h>
|
||||
#include "compress-io.h"
|
||||
#include <stddef.h>
|
||||
|
||||
#include "thread.h"
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#include "compress-io.h"
|
||||
|
||||
#ifndef EXTERN
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
|
|
@ -121,6 +121,8 @@ ptr S_create_thread_object(who, p_tc) const char *who; ptr p_tc; {
|
|||
|
||||
GUARDIANENTRIES(tc) = Snil;
|
||||
|
||||
LZ4OUTBUFFER(tc) = NULL;
|
||||
|
||||
tc_mutex_release()
|
||||
|
||||
return thread;
|
||||
|
@ -224,7 +226,9 @@ static IBOOL destroy_thread(tc) ptr tc; {
|
|||
}
|
||||
}
|
||||
|
||||
free((void *)THREADTC(thread));
|
||||
if (LZ4OUTBUFFER(tc) != NULL) free(LZ4OUTBUFFER(tc));
|
||||
|
||||
free((void *)tc);
|
||||
THREADTC(thread) = 0; /* mark it dead */
|
||||
status = 1;
|
||||
break;
|
||||
|
|
2
checkin
2
checkin
|
@ -294,7 +294,7 @@ endif
|
|||
|
||||
delete:
|
||||
|
||||
set tmpfiles = `(cd $W; find . -name zlib -prune -o -type f -print)`
|
||||
set tmpfiles = `(cd $W; find . -name zlib -prune -o -name lz4 -prune -o -type f -print)`
|
||||
set files = ()
|
||||
foreach x ($tmpfiles)
|
||||
set files = ($x $files)
|
||||
|
|
48
csug/io.stex
48
csug/io.stex
|
@ -208,8 +208,10 @@ Section~\ref{TSPL:SECTOPENINGFILES} of {\TSPLFOUR}.
|
|||
\item[\var{compressed}:]
|
||||
An output file should be compressed when written; and a compressed input
|
||||
file should be decompressed when read. The compression format for output
|
||||
is determined by the \scheme{compress-format} parameter, while the compression
|
||||
format on input is inferred.
|
||||
is determined by the \index{\scheme{compress-format}}\scheme{compress-format}
|
||||
parameter, while the compression format on input is inferred.
|
||||
The compression level, which is relevant only for output, is determined
|
||||
by the \index{\scheme{compress-level}}\scheme{compress-level} parameter.
|
||||
|
||||
\item[\var{replace}:]
|
||||
For output files only, replace (remove and recreate) the existing file if
|
||||
|
@ -975,8 +977,10 @@ will be compressed.
|
|||
If the port is an input port, subsequent input will be decompressed
|
||||
if and only if the port is currently pointing at compressed data.
|
||||
The compression format for output
|
||||
is determined by the \scheme{compress-format} parameter, while the compression
|
||||
format on input is inferred.
|
||||
is determined by the \index{\scheme{compress-format}}\scheme{compress-format}
|
||||
parameter, while the compression format on input is inferred.
|
||||
The compression level, which is relevant only for output, is determined
|
||||
by the \index{\scheme{compress-level}}\scheme{compress-level} parameter.
|
||||
This procedure has no effect if the port is already set for compression.
|
||||
|
||||
%----------------------------------------------------------------------------
|
||||
|
@ -986,23 +990,41 @@ This procedure has no effect if the port is already set for compression.
|
|||
\endnoskipentryheader
|
||||
|
||||
\noindent
|
||||
\scheme{compress-format} is a parameter that determines the
|
||||
compression algorithm and format that is used for output. Currently,
|
||||
the possible values of the parameter are \scheme{'lz4} (the default)
|
||||
and \scheme{'gzip}.
|
||||
\scheme{compress-format} determines the
|
||||
compression algorithm and format used for output. Currently,
|
||||
the possible values of the parameter are the symbols \scheme{lz4} (the default)
|
||||
and \scheme{gzip}.
|
||||
|
||||
The \scheme{'lz4} format uses the LZ4 compression library developed by
|
||||
The \scheme{lz4} format uses the LZ4 compression library developed by
|
||||
Yann Collet.
|
||||
It is therefore compatible with the \scheme{lz4} program, which
|
||||
means that \scheme{lz4} may be used to uncompress files produced
|
||||
by {\ChezScheme} and visa versa.
|
||||
|
||||
The \scheme{'gzip} format uses the zlib compression library developed by
|
||||
The \scheme{gzip} format uses the zlib compression library developed by
|
||||
Jean-loup Gailly and Mark Adler.
|
||||
It is therefore compatible with the \scheme{gzip} program, which
|
||||
means that \scheme{gzip} may be used to uncompress files produced
|
||||
by {\ChezScheme} and visa versa.
|
||||
|
||||
Reading \scheme{lz4}-compressed data tends to be much faster than reading
|
||||
\scheme{gzip}-compressed data, while \scheme{gzip}-compressed data tends to
|
||||
be significantly smaller.
|
||||
|
||||
%----------------------------------------------------------------------------
|
||||
\entryheader
|
||||
\formdef{compress-level}{\categorythreadparameter}{compress-level}
|
||||
\listlibraries
|
||||
\endnoskipentryheader
|
||||
|
||||
\noindent
|
||||
\scheme{compress-level} determines the amount of effort spent on
|
||||
compression and is thus relevant only for output.
|
||||
It can be set to one of the symbols \scheme{low},
|
||||
\scheme{medium}, \scheme{high}, or \scheme{maximum}, which are
|
||||
listed in order from shortest to longest expected compression time
|
||||
and least to greatest expected effectiveness.
|
||||
Its default value is \scheme{medium}.
|
||||
|
||||
\section{String Ports\label{SECTIOSTRINGPORTS}}
|
||||
|
||||
|
@ -1858,7 +1880,11 @@ The default behavior is to raise an exception.
|
|||
The mutually exclusive \scheme{compressed} and
|
||||
\scheme{uncompressed} options determine whether the output file is to
|
||||
be compressed.
|
||||
The compression format is determined by the \scheme{compress-format} parameter.
|
||||
The compression format and level are determined by the
|
||||
\index{\scheme{compress-format}}\scheme{compress-format}
|
||||
and
|
||||
\index{\scheme{compress-level}}\scheme{compress-level}
|
||||
parameters.
|
||||
Files are uncompressed by default, so the \scheme{uncompressed}
|
||||
option is useful only as documentation.
|
||||
|
||||
|
|
|
@ -1179,7 +1179,12 @@ The result is the raw compressed data with a minimal header to record
|
|||
the uncompressed size and the compression mode. The result does not include
|
||||
the header that is written by port-based compression using the
|
||||
\scheme{compressed} option. The compression format is determined by the
|
||||
\scheme{compress-format} parameter.
|
||||
\index{\scheme{compress-format}}\scheme{compress-format}
|
||||
parameter.
|
||||
The compression level is fixed to some default determined by the
|
||||
format; it is not affected by the
|
||||
\index{\scheme{compress-level}}\scheme{compress-level}
|
||||
parameter.
|
||||
|
||||
|
||||
%----------------------------------------------------------------------------
|
||||
|
|
|
@ -2471,6 +2471,11 @@ When this parameter is \scheme{#t}, the default, \scheme{compile-file},
|
|||
\scheme{compile-program}, \scheme{compile-to-file},
|
||||
\scheme{compile-whole-program}, and \scheme{strip-fasl-file} compress
|
||||
the object files they create.
|
||||
The compression format and level are determined by the
|
||||
\index{\scheme{compress-format}}\scheme{compress-format}
|
||||
and
|
||||
\index{\scheme{compress-level}}\scheme{compress-level}
|
||||
parameters.
|
||||
|
||||
|
||||
%----------------------------------------------------------------------------
|
||||
|
|
|
@ -208,6 +208,16 @@ continuation invocation, the mutex is reacquired.
|
|||
Using \scheme{with-mutex} is generally more convenient and safer than using
|
||||
\scheme{mutex-acquire} and \scheme{mutex-release} directly.
|
||||
|
||||
%----------------------------------------------------------------------------
|
||||
\entryheader
|
||||
\formdef{mutex-name}{\categoryprocedure}{(mutex-name \var{mutex})}
|
||||
\returns the name associated with \var{mutex}, if any; otherwise \scheme{#f}
|
||||
\listlibraries
|
||||
\endentryheader
|
||||
|
||||
\noindent
|
||||
\var{mutex} must be a mutex.
|
||||
|
||||
\section{Conditions}
|
||||
|
||||
%----------------------------------------------------------------------------
|
||||
|
@ -284,6 +294,16 @@ condition identified by \var{cond}.
|
|||
\scheme{condition-broadcast} releases all of the threads waiting for the
|
||||
condition identified by \var{cond}.
|
||||
|
||||
%----------------------------------------------------------------------------
|
||||
\entryheader
|
||||
\formdef{condition-name}{\categoryprocedure}{(condition-name \var{condition})}
|
||||
\returns the name associated with \var{condition}, if any; otherwise \scheme{#f}
|
||||
\listlibraries
|
||||
\endentryheader
|
||||
|
||||
\noindent
|
||||
\var{condition} must be a condition.
|
||||
|
||||
\section{Locks\label{SECTTHREADLOCKS}}
|
||||
|
||||
\index{locks}%
|
||||
|
|
|
@ -11277,7 +11277,7 @@
|
|||
|
||||
|
||||
(mat bytevector-compress
|
||||
(parameters [compress-format 'gzip] [compress-format 'lz4])
|
||||
(parameters [compress-format 'gzip 'lz4])
|
||||
(error? (bytevector-compress 7))
|
||||
(error? (bytevector-compress "hello"))
|
||||
(error? (bytevector-uncompress 7))
|
||||
|
@ -11300,19 +11300,6 @@
|
|||
(error?
|
||||
;; Need at least 8 bytes for result size
|
||||
(bytevector-uncompress '#vu8(0 0 0 0 0 0 255)))
|
||||
(error?
|
||||
;; Fail if the uncompressed result is too big
|
||||
(bytevector-uncompress (let ([bv (bytevector-compress (string->utf8 "hello"))])
|
||||
(bytevector-u64-set! bv 0 (sub1 (bytevector-u64-ref bv 0 (endianness big))) (endianness big))
|
||||
bv)))
|
||||
(error?
|
||||
;; Fail if the uncompressed result is too small
|
||||
(bytevector-uncompress (let ([bv (bytevector-compress (string->utf8 "hello"))])
|
||||
(bytevector-u64-set! bv 0 (add1 (bytevector-u64-ref bv 0 (endianness big))) (endianness big))
|
||||
bv)))
|
||||
(error?
|
||||
;; Compressed data always starts with 0x78, so this one isn't valid:
|
||||
(bytevector-uncompress '#vu8(0 0 0 0 0 0 0 255 1 2 3)))
|
||||
(error?
|
||||
;; Claming a too-large size in the header should fail with a suitable message:
|
||||
(bytevector-uncompress '#vu8(255 255 255 255 255 255 255 255 1 2 3)))
|
||||
|
|
59
mats/io.ms
59
mats/io.ms
|
@ -2126,8 +2126,63 @@
|
|||
(= q (custom-port-buffer-size)))))
|
||||
)
|
||||
|
||||
(mat compress-parameters
|
||||
(error? ; unsupported format
|
||||
(compress-format 'foo))
|
||||
(error? ; unsupported format
|
||||
(compress-format "gzip"))
|
||||
(eq? (compress-format) 'lz4)
|
||||
(eq? (parameterize ([compress-format 'gzip]) (compress-format)) 'gzip)
|
||||
(eq? (parameterize ([compress-format 'lz4]) (compress-format)) 'lz4)
|
||||
(error? ; unsupported level
|
||||
(compress-level 'foo))
|
||||
(error? ; unsupported level
|
||||
(compress-level 1))
|
||||
(eq? (compress-level) 'medium)
|
||||
(eq? (parameterize ([compress-level 'low]) (compress-level)) 'low)
|
||||
(eq? (parameterize ([compress-level 'medium]) (compress-level)) 'medium)
|
||||
(eq? (parameterize ([compress-level 'high]) (compress-level)) 'high)
|
||||
(eq? (parameterize ([compress-level 'maximum]) (compress-level)) 'maximum)
|
||||
(begin
|
||||
(define (fnlength ifn) (call-with-port (open-file-input-port ifn) port-length))
|
||||
(define (compress-file ifn ofn fmt lvl)
|
||||
(call-with-port (open-file-input-port ifn)
|
||||
(lambda (ip)
|
||||
(call-with-port (parameterize ([compress-format fmt] [compress-level lvl])
|
||||
(open-file-output-port ofn (file-options compressed replace)))
|
||||
(lambda (op) (put-bytevector op (get-bytevector-all ip))))))
|
||||
(fnlength ofn))
|
||||
(define (compress-file-test fmt)
|
||||
(let ([orig (fnlength "prettytest.ss")]
|
||||
[low (compress-file "prettytest.ss" "testfile.ss" fmt 'low)]
|
||||
[medium (compress-file "prettytest.ss" "testfile.ss" fmt 'medium)]
|
||||
[high (compress-file "prettytest.ss" "testfile.ss" fmt 'high)]
|
||||
[maximum (compress-file "prettytest.ss" "testfile.ss" fmt 'maximum)])
|
||||
(define-syntax test1
|
||||
(syntax-rules ()
|
||||
[(_ level)
|
||||
(unless (< level orig) (errorf #f "~s ~s did not compress" fmt 'level))]))
|
||||
(define-syntax test2
|
||||
(syntax-rules ()
|
||||
[(_ level1 level2)
|
||||
(unless (<= level2 level1) (errorf #f "~s ~s did worse than ~s" fmt 'level2 'level1))]))
|
||||
(test1 low)
|
||||
(test1 medium)
|
||||
(test1 high)
|
||||
(test1 maximum)
|
||||
(test2 low medium)
|
||||
(test2 medium high)
|
||||
(test2 high maximum)
|
||||
(unless (< maximum low) (errorf #f "~s maximum didn't do better than low" fmt))))
|
||||
(compress-file-test 'lz4)
|
||||
(compress-file-test 'gzip)
|
||||
#t)
|
||||
)
|
||||
|
||||
(mat compression
|
||||
(parameters [compress-format 'gzip] [compress-format 'lz4])
|
||||
(parameters [compress-format 'gzip 'lz4] [compress-level 'low 'medium 'high 'maximum])
|
||||
(and (memq (compress-format) '(gzip lz4)) #t)
|
||||
(and (memq (compress-level) '(low medium high maximum)) #t)
|
||||
(let ()
|
||||
(define cp
|
||||
(lambda (src dst)
|
||||
|
@ -3072,7 +3127,7 @@
|
|||
)
|
||||
|
||||
(mat compression-textual
|
||||
(parameters [compress-format 'gzip] [compress-format 'lz4])
|
||||
(parameters [compress-format 'gzip 'lz4] [compress-level 'low 'medium 'high 'maximum])
|
||||
(let ()
|
||||
(define cp
|
||||
(lambda (src dst)
|
||||
|
|
14
mats/mat.ss
14
mats/mat.ss
|
@ -20,12 +20,16 @@
|
|||
(define-syntax mat
|
||||
(lambda (x)
|
||||
(syntax-case x (parameters)
|
||||
[(_ x (parameters [param val] ...) e ...)
|
||||
#'(for-each (lambda (p v)
|
||||
[(_ x (parameters [param val ...] ...) e ...)
|
||||
#'(let f ([p* (list param ...)] [v** (list (list val ...) ...)])
|
||||
(if (null? p*)
|
||||
(mat x e ...)
|
||||
(let ([p (car p*)])
|
||||
(for-each
|
||||
(lambda (v)
|
||||
(parameterize ([p v])
|
||||
(mat x e ...)))
|
||||
(list param ...)
|
||||
(list val ...))]
|
||||
(f (cdr p*) (cdr v**))))
|
||||
(car v**)))))]
|
||||
[(_ x e ...)
|
||||
(with-syntax ([(source ...)
|
||||
(map (lambda (clause)
|
||||
|
|
|
@ -3626,9 +3626,6 @@ bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress:
|
|||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: "hello" is not a bytevector".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: invalid data in source bytevector #vu8()".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: invalid data in source bytevector #vu8(0 0 0 0 0 0 ...)".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: uncompressed #vu8(0 0 0 0 0 0 ...) is larger than expected size".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: uncompressed size 5 for #vu8(0 0 0 0 0 0 ...) is smaller than expected size 6".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: invalid data in source bytevector #vu8(0 0 0 0 0 0 ...)".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: bytevector #vu8(255 255 255 255 255 255 ...) claims invalid uncompressed size <int>".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-compress: 7 is not a bytevector".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-compress: "hello" is not a bytevector".
|
||||
|
@ -3636,9 +3633,6 @@ bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress:
|
|||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: "hello" is not a bytevector".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: invalid data in source bytevector #vu8()".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: invalid data in source bytevector #vu8(0 0 0 0 0 0 ...)".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: internal error uncompressing #vu8(128 0 0 0 0 0 ...)".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: uncompressed size 5 for #vu8(128 0 0 0 0 0 ...) is smaller than expected size 6".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: invalid data in source bytevector #vu8(0 0 0 0 0 0 ...)".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: bytevector #vu8(255 255 255 255 255 255 ...) claims invalid uncompressed size <int>".
|
||||
misc.mo:Expected error in mat compiler1: "variable i-am-not-bound is not bound".
|
||||
misc.mo:Expected error in mat compiler1: "attempt to apply non-procedure oops".
|
||||
|
@ -6798,6 +6792,22 @@ io.mo:Expected error in mat custom-port-buffer-size: "custom-port-buffer-size: 0
|
|||
io.mo:Expected error in mat custom-port-buffer-size: "custom-port-buffer-size: -15 is not a positive fixnum".
|
||||
io.mo:Expected error in mat custom-port-buffer-size: "custom-port-buffer-size: <int> is not a positive fixnum".
|
||||
io.mo:Expected error in mat custom-port-buffer-size: "custom-port-buffer-size: 1024.0 is not a positive fixnum".
|
||||
io.mo:Expected error in mat compress-parameters: "compress-format: foo is not a supported format".
|
||||
io.mo:Expected error in mat compress-parameters: "compress-format: "gzip" is not a supported format".
|
||||
io.mo:Expected error in mat compress-parameters: "compress-level: foo is not a supported level".
|
||||
io.mo:Expected error in mat compress-parameters: "compress-level: 1 is not a supported level".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: #<output port string> is not a file port".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: cannot compress input/output port #<binary input/output port testfile.ss>".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: #<output port string> is not a file port".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: cannot compress input/output port #<binary input/output port testfile.ss>".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: #<output port string> is not a file port".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: cannot compress input/output port #<binary input/output port testfile.ss>".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: #<output port string> is not a file port".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: cannot compress input/output port #<binary input/output port testfile.ss>".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: #<output port string> is not a file port".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: cannot compress input/output port #<binary input/output port testfile.ss>".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: #<output port string> is not a file port".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: cannot compress input/output port #<binary input/output port testfile.ss>".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: #<output port string> is not a file port".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: cannot compress input/output port #<binary input/output port testfile.ss>".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: #<output port string> is not a file port".
|
||||
|
|
|
@ -3626,8 +3626,12 @@ bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress:
|
|||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: "hello" is not a bytevector".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: invalid data in source bytevector #vu8()".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: invalid data in source bytevector #vu8(0 0 0 0 0 0 ...)".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: uncompressed #vu8(0 0 0 0 0 0 ...) is larger than expected size".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: uncompressed size 5 for #vu8(0 0 0 0 0 0 ...) is smaller than expected size 6".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: bytevector #vu8(255 255 255 255 255 255 ...) claims invalid uncompressed size <int>".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-compress: 7 is not a bytevector".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-compress: "hello" is not a bytevector".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: 7 is not a bytevector".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: "hello" is not a bytevector".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: invalid data in source bytevector #vu8()".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: invalid data in source bytevector #vu8(0 0 0 0 0 0 ...)".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: bytevector #vu8(255 255 255 255 255 255 ...) claims invalid uncompressed size <int>".
|
||||
misc.mo:Expected error in mat compiler1: "variable i-am-not-bound is not bound".
|
||||
|
@ -6788,6 +6792,24 @@ io.mo:Expected error in mat custom-port-buffer-size: "custom-port-buffer-size: 0
|
|||
io.mo:Expected error in mat custom-port-buffer-size: "custom-port-buffer-size: -15 is not a positive fixnum".
|
||||
io.mo:Expected error in mat custom-port-buffer-size: "custom-port-buffer-size: <int> is not a positive fixnum".
|
||||
io.mo:Expected error in mat custom-port-buffer-size: "custom-port-buffer-size: 1024.0 is not a positive fixnum".
|
||||
io.mo:Expected error in mat compress-parameters: "compress-format: foo is not a supported format".
|
||||
io.mo:Expected error in mat compress-parameters: "compress-format: "gzip" is not a supported format".
|
||||
io.mo:Expected error in mat compress-parameters: "compress-level: foo is not a supported level".
|
||||
io.mo:Expected error in mat compress-parameters: "compress-level: 1 is not a supported level".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: #<output port string> is not a file port".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: cannot compress input/output port #<binary input/output port testfile.ss>".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: #<output port string> is not a file port".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: cannot compress input/output port #<binary input/output port testfile.ss>".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: #<output port string> is not a file port".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: cannot compress input/output port #<binary input/output port testfile.ss>".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: #<output port string> is not a file port".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: cannot compress input/output port #<binary input/output port testfile.ss>".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: #<output port string> is not a file port".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: cannot compress input/output port #<binary input/output port testfile.ss>".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: #<output port string> is not a file port".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: cannot compress input/output port #<binary input/output port testfile.ss>".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: #<output port string> is not a file port".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: cannot compress input/output port #<binary input/output port testfile.ss>".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: #<output port string> is not a file port".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: cannot compress input/output port #<binary input/output port testfile.ss>".
|
||||
io.mo:Expected error in mat bytevector-input-port: "incorrect argument count in call (open-bytevector-input-port)".
|
||||
|
|
|
@ -58,16 +58,29 @@ Online versions of both books can be found at
|
|||
%-----------------------------------------------------------------------------
|
||||
\section{Functionality Changes}\label{section:functionality}
|
||||
|
||||
\subsection{Compression format (9.5.3)}
|
||||
\subsection{Compression format and level (9.5.3)}
|
||||
|
||||
The default format for compressed-file writing is now LZ4, while {\tt
|
||||
Support for LZ4 compression has been added.
|
||||
LZ4 is now the default format when compressing files (including
|
||||
object files produced by the compiler) and bytevectors, while {\tt
|
||||
gzip} is still supported and can be enabled by setting
|
||||
\scheme{compress-format} to \scheme{'gzip}. Reading in compressed mode
|
||||
the new \scheme{compress-format} parameter to the symbol \scheme{gzip} instead of the
|
||||
default \scheme{lz4}. Reading in compressed mode
|
||||
infers the format, so reading {\tt gzip}-compressed files will still
|
||||
work without changing \scheme{compress-format}. Reading LZ4-format
|
||||
files tends to be much faster than reading {\tt gzip}-format files, in
|
||||
most cases nearly eliminating the load-time cost of compressing
|
||||
compiled files.
|
||||
work without changing \scheme{compress-format}. Reading LZ4-format
|
||||
files tends to be much faster than reading {\tt gzip}-format files,
|
||||
while {\tt gzip}-compressed files tend to be smaller.
|
||||
In particular, object files created by the compiler now tend to be
|
||||
larger but load more quickly.
|
||||
|
||||
The new \scheme{compress-level} parameter can be used to control
|
||||
the amount of time spent on file compression (but not
|
||||
bytevector compression).
|
||||
It can be set to one of the symbols \scheme{low},
|
||||
\scheme{medium}, \scheme{high}, and \scheme{maximum}, which are
|
||||
listed in order from shortest to longest compression time and least
|
||||
to greatest effectiveness.
|
||||
The default value is \scheme{medium}.
|
||||
|
||||
\subsection{Mutexes and condition variables can have names (9.5.3)}
|
||||
|
||||
|
|
47
s/Mf-base
47
s/Mf-base
|
@ -24,15 +24,23 @@ o = 3
|
|||
# d is the debug level at which the system should be built
|
||||
d = 0
|
||||
|
||||
# cl (xcl) determines the commonization level
|
||||
# cl determines the commonization level
|
||||
cl = (commonization-level)
|
||||
|
||||
# i determines whether inspector-information is generated: f for false, t for true
|
||||
i = f
|
||||
|
||||
# cp0 (xcp0) determines the number of cp0 (source optimizer) iterations run
|
||||
# cp0 determines the number of cp0 (source optimizer) iterations run
|
||||
cp0 = 2
|
||||
xcp0 = 2
|
||||
|
||||
# cc determines whether compiled files are compressed
|
||||
cc = t
|
||||
|
||||
# xf determines the compression foramt
|
||||
xf = (compress-format)
|
||||
|
||||
# xl determine the compression level
|
||||
xl = (compress-level)
|
||||
|
||||
# p (xp) determines whether source profiling is enabled: f for false, t for true.
|
||||
p = f
|
||||
|
@ -214,6 +222,9 @@ clean: profileclean
|
|||
'(optimize-level $o)'\
|
||||
'(debug-level $d)'\
|
||||
'(commonization-level $(cl))'\
|
||||
'(compile-compressed #$(cc))'\
|
||||
'(compress-format $(xf))'\
|
||||
'(compress-level $(xl))'\
|
||||
'(when #$p (compile-profile (quote source)))'\
|
||||
'(when #$(bp) (compile-profile (quote block)))'\
|
||||
'(when #$(loadspd) (profile-load-data "${ProfileDumpSource}"))'\
|
||||
|
@ -238,6 +249,9 @@ clean: profileclean
|
|||
'(optimize-level $o)'\
|
||||
'(debug-level $d)'\
|
||||
'(commonization-level $(cl))'\
|
||||
'(compile-compressed #$(cc))'\
|
||||
'(compress-format $(xf))'\
|
||||
'(compress-level $(xl))'\
|
||||
'(when #$p (compile-profile (quote source)))'\
|
||||
'(when #$(bp) (compile-profile (quote block)))'\
|
||||
'(when #$(loadspd) (profile-load-data "${ProfileDumpSource}"))'\
|
||||
|
@ -265,6 +279,9 @@ clean: profileclean
|
|||
'(optimize-level $o)'\
|
||||
'(debug-level $d)'\
|
||||
'(commonization-level $(cl))'\
|
||||
'(compile-compressed #$(cc))'\
|
||||
'(compress-format $(xf))'\
|
||||
'(compress-level $(xl))'\
|
||||
'(generate-inspector-information #$i)'\
|
||||
'(subset-mode (quote system))'\
|
||||
'(compile-file "$*.ss" "$*.so")'\
|
||||
|
@ -275,6 +292,9 @@ clean: profileclean
|
|||
'(optimize-level $o)'\
|
||||
'(debug-level $d)'\
|
||||
'(commonization-level $(cl))'\
|
||||
'(compile-compressed #$(cc))'\
|
||||
'(compress-format $(xf))'\
|
||||
'(compress-level $(xl))'\
|
||||
'(when #$(xp) (compile-profile (quote source)))'\
|
||||
'(when #$(xbp) (compile-profile (quote block)))'\
|
||||
'(generate-inspector-information #$i)'\
|
||||
|
@ -344,6 +364,9 @@ cmacros.so: cmacros.ss machine.def layout.ss
|
|||
'(optimize-level $o)'\
|
||||
'(debug-level $d)'\
|
||||
'(commonization-level $(cl))'\
|
||||
'(compile-compressed #$(cc))'\
|
||||
'(compress-format $(xf))'\
|
||||
'(compress-level $(xl))'\
|
||||
'(generate-inspector-information #$i)'\
|
||||
'(subset-mode (quote system))'\
|
||||
'(compile-file "$*.ss" "$*.so")'\
|
||||
|
@ -356,6 +379,9 @@ priminfo.so: priminfo.ss primdata.ss cmacros.so
|
|||
'(optimize-level $o)'\
|
||||
'(debug-level $d)'\
|
||||
'(commonization-level $(cl))'\
|
||||
'(compile-compressed #$(cc))'\
|
||||
'(compress-format $(xf))'\
|
||||
'(compress-level $(xl))'\
|
||||
'(generate-inspector-information #$i)'\
|
||||
'(subset-mode (quote system))'\
|
||||
'(compile-file "$*.ss" "$*.so")'\
|
||||
|
@ -369,6 +395,9 @@ mkheader.so: mkheader.ss cmacros.so primvars.so env.so
|
|||
'(optimize-level $o)'\
|
||||
'(debug-level $d)'\
|
||||
'(commonization-level $(cl))'\
|
||||
'(compile-compressed #$(cc))'\
|
||||
'(compress-format $(xf))'\
|
||||
'(compress-level $(xl))'\
|
||||
'(generate-inspector-information #$i)'\
|
||||
'(subset-mode (quote system))'\
|
||||
'(compile-file "$*.ss" "$*.so")'\
|
||||
|
@ -381,6 +410,9 @@ nanopass.so: $(shell echo ../nanopass/nanopass/*) ../nanopass/nanopass.ss
|
|||
'(optimize-level $o)'\
|
||||
'(debug-level $d)'\
|
||||
'(commonization-level $(cl))'\
|
||||
'(compile-compressed #$(cc))'\
|
||||
'(compress-format $(xf))'\
|
||||
'(compress-level $(xl))'\
|
||||
'(generate-inspector-information #$i)'\
|
||||
'(collect-trip-bytes (expt 2 24))'\
|
||||
'(collect-request-handler (lambda () (collect 0 1)))'\
|
||||
|
@ -404,6 +436,9 @@ script.all makescript:
|
|||
'(optimize-level $o)'\
|
||||
'(debug-level $d)'\
|
||||
'(commonization-level $(cl))'\
|
||||
'(compile-compressed #$(cc))'\
|
||||
'(compress-format $(xf))'\
|
||||
'(compress-level $(xl))'\
|
||||
'(when #$p (compile-profile (quote source)))'\
|
||||
'(when #$(bp) (compile-profile (quote block)))'\
|
||||
'(when #$(loadspd) (profile-load-data "${ProfileDumpSource}"))'\
|
||||
|
@ -440,6 +475,9 @@ script-static.all:
|
|||
'(optimize-level $o)'\
|
||||
'(debug-level $d)'\
|
||||
'(commonization-level $(cl))'\
|
||||
'(compile-compressed #$(cc))'\
|
||||
'(compress-format $(xf))'\
|
||||
'(compress-level $(xl))'\
|
||||
'(when #$p (compile-profile (quote source)))'\
|
||||
'(when #$(bp) (compile-profile (quote block)))'\
|
||||
'(generate-inspector-information #$i)'\
|
||||
|
@ -462,6 +500,9 @@ script-dynamic.all:
|
|||
'(optimize-level $o)'\
|
||||
'(debug-level $d)'\
|
||||
'(commonization-level $(cl))'\
|
||||
'(compile-compressed #$(cc))'\
|
||||
'(compress-format $(xf))'\
|
||||
'(compress-level $(xl))'\
|
||||
'(when #$p (compile-profile (quote source)))'\
|
||||
'(when #$(bp) (compile-profile (quote block)))'\
|
||||
'(generate-inspector-information #$i)'\
|
||||
|
|
38
s/back.ss
38
s/back.ss
|
@ -156,12 +156,38 @@
|
|||
x)))
|
||||
|
||||
(define-who compress-format
|
||||
($make-thread-parameter
|
||||
'lz4
|
||||
(lambda (x)
|
||||
(unless (or (eq? x 'lz4) (eq? x 'gzip))
|
||||
($oops who "~s is not a supported format" x))
|
||||
x)))
|
||||
(case-lambda
|
||||
[()
|
||||
(let ([x ($tc-field 'compress-format ($tc))])
|
||||
(cond
|
||||
[(eqv? x (constant COMPRESS-GZIP)) 'gzip]
|
||||
[(eqv? x (constant COMPRESS-LZ4)) 'lz4]
|
||||
[else ($oops who "unexpected $compress-format value ~s" x)]))]
|
||||
[(x)
|
||||
($tc-field 'compress-format ($tc)
|
||||
(case x
|
||||
[(gzip) (constant COMPRESS-GZIP)]
|
||||
[(lz4) (constant COMPRESS-LZ4)]
|
||||
[else ($oops who "~s is not a supported format" x)]))]))
|
||||
|
||||
(define-who compress-level
|
||||
(case-lambda
|
||||
[()
|
||||
(let ([x ($tc-field 'compress-level ($tc))])
|
||||
(cond
|
||||
[(eqv? x (constant COMPRESS-LOW)) 'low]
|
||||
[(eqv? x (constant COMPRESS-MEDIUM)) 'medium]
|
||||
[(eqv? x (constant COMPRESS-HIGH)) 'high]
|
||||
[(eqv? x (constant COMPRESS-MAX)) 'maximum]
|
||||
[else ($oops who "unexpected $compress-level value ~s" x)]))]
|
||||
[(x)
|
||||
($tc-field 'compress-level ($tc)
|
||||
(case x
|
||||
[(low) (constant COMPRESS-LOW)]
|
||||
[(medium) (constant COMPRESS-MEDIUM)]
|
||||
[(high) (constant COMPRESS-HIGH)]
|
||||
[(maximum) (constant COMPRESS-MAX)]
|
||||
[else ($oops who "~s is not a supported level" x)]))]))
|
||||
|
||||
(define-who debug-level
|
||||
($make-thread-parameter
|
||||
|
|
|
@ -1454,25 +1454,23 @@
|
|||
)
|
||||
|
||||
(let ()
|
||||
;; Store uncompressed size as u64, using high bit to indicate LZ4:
|
||||
;; Store uncompressed size as u64, using low bits to indicate compression format:
|
||||
(define uncompressed-length-length (ftype-sizeof integer-64))
|
||||
;; Always big-endian, so that compressed data is portable.
|
||||
;; It might be useful somehow that valid compressed data always starts
|
||||
;; with a 0 or 128 byte; otherwise, the expected size would be unrealistically big.
|
||||
(define uncompressed-length-endianness (endianness big))
|
||||
|
||||
(define $bytevector-compress-size
|
||||
(foreign-procedure "(cs)bytevector_compress_size" (iptr boolean) uptr))
|
||||
(foreign-procedure "(cs)bytevector_compress_size" (iptr int) uptr))
|
||||
(define $bytevector-compress
|
||||
(foreign-procedure "(cs)bytevector_compress" (scheme-object iptr iptr scheme-object iptr iptr boolean) scheme-object))
|
||||
(foreign-procedure "(cs)bytevector_compress" (scheme-object iptr iptr scheme-object iptr iptr int) scheme-object))
|
||||
(define $bytevector-uncompress
|
||||
(foreign-procedure "(cs)bytevector_uncompress" (scheme-object iptr iptr scheme-object iptr iptr boolean) scheme-object))
|
||||
(foreign-procedure "(cs)bytevector_uncompress" (scheme-object iptr iptr scheme-object iptr iptr int) scheme-object))
|
||||
|
||||
(set-who! bytevector-compress
|
||||
(lambda (bv)
|
||||
(unless (bytevector? bv) (not-a-bytevector who bv))
|
||||
(let* ([as-gz? (eq? 'gzip (compress-format))]
|
||||
[dest-max-len ($bytevector-compress-size (bytevector-length bv) as-gz?)]
|
||||
(let* ([fmt ($tc-field 'compress-format ($tc))]
|
||||
[dest-max-len ($bytevector-compress-size (bytevector-length bv) fmt)]
|
||||
[dest-alloc-len (min (+ dest-max-len uncompressed-length-length)
|
||||
;; In the unlikely event of a non-fixnum requested size...
|
||||
(constant maximum-bytevector-length))]
|
||||
|
@ -1483,34 +1481,25 @@
|
|||
bv
|
||||
0
|
||||
(bytevector-length bv)
|
||||
as-gz?)])
|
||||
fmt)])
|
||||
(cond
|
||||
[(string? r)
|
||||
($oops who r bv)]
|
||||
[else
|
||||
($bytevector-u64-set! dest-bv 0 (bytevector-length bv) uncompressed-length-endianness who)
|
||||
(unless as-gz? (bytevector-u8-set! dest-bv 0 128)) ; set high bit for LZ4
|
||||
(bytevector-truncate! dest-bv (fx+ r uncompressed-length-length))])))))
|
||||
(let ([tag (bitwise-ior
|
||||
(bitwise-arithmetic-shift-left (bytevector-length bv) (constant COMPRESS-FORMAT-BITS))
|
||||
fmt)])
|
||||
($bytevector-u64-set! dest-bv 0 tag uncompressed-length-endianness who)
|
||||
(bytevector-truncate! dest-bv (fx+ r uncompressed-length-length)))])))))
|
||||
|
||||
(set-who! bytevector-uncompress
|
||||
(lambda (bv)
|
||||
(unless (bytevector? bv) (not-a-bytevector who bv))
|
||||
(unless (>= (bytevector-length bv) uncompressed-length-length)
|
||||
($oops who "invalid data in source bytevector ~s" bv))
|
||||
(let* ([as-gz? (not (fx= 128 (bytevector-u8-ref bv 0)))]
|
||||
[dest-length (cond
|
||||
[as-gz?
|
||||
($bytevector-u64-ref bv 0 uncompressed-length-endianness who)]
|
||||
;; Need to skip high bit; likely can skip first 4 bytes
|
||||
[(and (fx= 0 (bytevector-u8-ref bv 1))
|
||||
(fx= 0 (bytevector-u8-ref bv 2))
|
||||
(fx= 0 (bytevector-u8-ref bv 3)))
|
||||
($bytevector-u32-ref bv 4 uncompressed-length-endianness who)]
|
||||
[else
|
||||
;; Clear high bit the hard way
|
||||
(+ ($bytevector-u32-ref bv 4 uncompressed-length-endianness who)
|
||||
(let ([v ($bytevector-u32-ref bv 0 uncompressed-length-endianness who)])
|
||||
((bitwise-arithmetic-shift-left (- v #x80000000) 32))))])])
|
||||
(let* ([tag ($bytevector-u64-ref bv 0 uncompressed-length-endianness who)]
|
||||
[fmt (logand tag (fx- (fxsll 1 (constant COMPRESS-FORMAT-BITS)) 1))]
|
||||
[dest-length (bitwise-arithmetic-shift-right tag (constant COMPRESS-FORMAT-BITS))])
|
||||
(unless (and (fixnum? dest-length)
|
||||
($fxu< dest-length (constant maximum-bytevector-length)))
|
||||
($oops who "bytevector ~s claims invalid uncompressed size ~s" bv dest-length))
|
||||
|
@ -1521,7 +1510,7 @@
|
|||
bv
|
||||
uncompressed-length-length
|
||||
(fx- (bytevector-length bv) uncompressed-length-length)
|
||||
as-gz?)])
|
||||
fmt)])
|
||||
(cond
|
||||
[(string? r) ($oops who r bv)]
|
||||
[(fx= r dest-length) dest-bv]
|
||||
|
|
12
s/cmacros.ss
12
s/cmacros.ss
|
@ -531,6 +531,15 @@
|
|||
|
||||
(define-constant SEOF -1)
|
||||
|
||||
(define-constant COMPRESS-GZIP 0)
|
||||
(define-constant COMPRESS-LZ4 1)
|
||||
(define-constant COMPRESS-FORMAT-BITS 3)
|
||||
|
||||
(define-constant COMPRESS-LOW 0)
|
||||
(define-constant COMPRESS-MEDIUM 1)
|
||||
(define-constant COMPRESS-HIGH 2)
|
||||
(define-constant COMPRESS-MAX 3)
|
||||
|
||||
(define-constant SICONV-DUNNO 0)
|
||||
(define-constant SICONV-INVALID 1)
|
||||
(define-constant SICONV-INCOMPLETE 2)
|
||||
|
@ -1371,6 +1380,9 @@
|
|||
[ptr suppress-primitive-inlining]
|
||||
[ptr default-record-equal-procedure]
|
||||
[ptr default-record-hash-procedure]
|
||||
[ptr compress-format]
|
||||
[ptr compress-level]
|
||||
[void* lz4-out-buffer]
|
||||
[U64 instr-counter]
|
||||
[U64 alloc-counter]
|
||||
[ptr parameters]))
|
||||
|
|
22
s/io.ss
22
s/io.ss
|
@ -264,7 +264,7 @@ implementation notes:
|
|||
(foreign-procedure "(cs)new_open_output_fd"
|
||||
(string int
|
||||
boolean boolean boolean
|
||||
boolean boolean boolean boolean boolean)
|
||||
boolean boolean boolean boolean)
|
||||
scheme-object))
|
||||
(define $open-input/output-fd
|
||||
(foreign-procedure "(cs)new_open_input_output_fd"
|
||||
|
@ -310,7 +310,7 @@ implementation notes:
|
|||
(define $compress-input-fd
|
||||
(foreign-procedure "(cs)compress_input_fd" (int integer-64) scheme-object))
|
||||
(define $compress-output-fd
|
||||
(foreign-procedure "(cs)compress_output_fd" (int boolean) scheme-object))
|
||||
(foreign-procedure "(cs)compress_output_fd" (int) scheme-object))
|
||||
(module (clear-open-files register-open-file registered-open-file? unregister-open-file)
|
||||
(define open-files #f)
|
||||
(define file-guardian)
|
||||
|
@ -645,14 +645,17 @@ implementation notes:
|
|||
|
||||
(define binary-file-port-close-port
|
||||
(lambda (who p)
|
||||
(unregister-open-file p)
|
||||
(let ([msg ($close-fd ($port-info p) (port-gz-mode p))])
|
||||
(unless (eq? #t msg) (port-oops who p msg)))
|
||||
(mark-port-closed! p)
|
||||
(when (input-port? p)
|
||||
(set-port-eof! p #f)
|
||||
(set-binary-port-input-size! p 0))
|
||||
(when (output-port? p) (set-binary-port-output-size! p 0))))
|
||||
(when (output-port? p) (set-binary-port-output-size! p 0))
|
||||
(unregister-open-file p)
|
||||
; mark port closed before closing fd. if an interrupt occurs, we'd prefer
|
||||
; that the fd's resources never be freed than to have an open port floating
|
||||
; around with fd resources that have already been freed.
|
||||
(mark-port-closed! p)
|
||||
(let ([msg ($close-fd ($port-info p) (port-gz-mode p))])
|
||||
(unless (eq? #t msg) (port-oops who p msg)))))
|
||||
|
||||
(define-syntax binary-file-port-port-position
|
||||
(syntax-rules ()
|
||||
|
@ -3185,7 +3188,7 @@ implementation notes:
|
|||
; reposition to 'unread' any compressed data in the input buffer
|
||||
(set-port-position! p fp)
|
||||
($compress-input-fd fd fp))
|
||||
($compress-output-fd fd (eq? (compress-format) 'gzip)))])
|
||||
($compress-output-fd fd))])
|
||||
(when (string? gzfd) ($oops who "failed for ~s: ~(~a~)" p gzfd))
|
||||
(unless (eqv? gzfd fd) ; uncompressed input port
|
||||
(assert (box? gzfd))
|
||||
|
@ -4091,8 +4094,7 @@ implementation notes:
|
|||
(let ([fd (critical-section
|
||||
($open-output-fd filename perms
|
||||
no-create no-fail no-truncate
|
||||
append lock replace compressed
|
||||
(and compressed (eq? (compress-format) 'gzip))))])
|
||||
append lock replace compressed))])
|
||||
(when (pair? fd) (open-oops who filename options fd))
|
||||
(open-binary-fd-output-port who filename fd #t b-mode lock compressed)))))
|
||||
|
||||
|
|
|
@ -926,6 +926,7 @@
|
|||
(compile-profile [sig [() -> (ptr)] [(ptr) -> (void)]] [flags unrestricted])
|
||||
(compile-program-handler [sig [() -> (procedure)] [(procedure) -> (void)]] [flags])
|
||||
(compress-format [sig [() -> (symbol)] [(sub-symbol) -> (void)]] [flags])
|
||||
(compress-level [sig [() -> (symbol)] [(sub-symbol) -> (void)]] [flags])
|
||||
(console-error-port [sig [() -> (textual-output-port)] [(textual-output-port) -> (void)]] [flags])
|
||||
(console-input-port [sig [() -> (textual-input-port)] [(textual-input-port) -> (void)]] [flags])
|
||||
(console-output-port [sig [() -> (textual-output-port)] [(textual-output-port) -> (void)]] [flags])
|
||||
|
|
Loading…
Reference in New Issue
Block a user