[Nickle] nickle: Branch 'master' - 3 commits
Bart Massey
bart at po8.org
Tue Oct 2 11:43:50 PDT 2007
It should be easy to add finalizer support to your
mark-sweep GC, and then just close the file in the finalizer
when it becomes unreferenced. This would be the traditional
solution, I think. Am I missing something?
Bart
In message <20071002085403.791D3114203 at keithp.com> you wrote:
> --===============1547860296==
>
> builtin-toplevel.c | 1
> ctype.5c | 20 ++++++++-----
> file.c | 79 +++++++++++++++++++++++++++++------------------------
> value.h | 1
> 4 files changed, 57 insertions(+), 44 deletions(-)
>
> New commits:
> commit 2278b93b7e760f1153847a0b3c36d07684f72e0c
> Author: Keith Packard <keithp at koto.keithp.com>
> Date: Tue Oct 2 01:53:02 2007 -0700
>
> Manage file buffer chains with explicit malloc/free.
>
> Buffer chains must have life equal to the file they belong to; an
> unreferenced file may still have buffered data, so the buffers cannot be
> reclaimed. The nickle GC does not have a separate pass that checks to see
> which objects can be freed, rather it assumes that such objects are
> self-contained.
>
> Hence, anything hanging off of an object which can refuse to
> be reclaimed must not have been allocated from the nickle GC system. Yes,
> this is a significant limitation to this allocator.
>
> Someday I'll figure out a good general fix for this problem, right now we'll
> stop segfaults when applications drop file references without closing them.
>
> diff --git a/file.c b/file.c
> index 77356b1..933b544 100644
> --- a/file.c
> +++ b/file.c
> @@ -472,6 +472,30 @@ ProcessInterrupt ()
> }
> }
>
> +static FileChainPtr
> +FileChainAlloc (FileChainPtr next, int size)
> +{
> + FileChainPtr ret;
> +
> + ret = malloc (sizeof (FileChain) + size);
> + ret->next = next;
> + ret->size = size;
> + ret->used = 0;
> + ret->ptr = 0;
> + return ret;
> +}
> +
> +static void
> +FileChainFree (FileChainPtr ic)
> +{
> + while (ic)
> + {
> + FileChainPtr next = ic->next;
> + free (ic);
> + ic = next;
> + }
> +}
> +
> int
> FileInit (void)
> {
> @@ -521,8 +545,6 @@ FileMark (void *object)
>
> FileFlush ((Value) file, False);
> MemReference (file->next);
> - MemReference (file->input);
> - MemReference (file->output);
> }
>
> void
> @@ -538,10 +560,14 @@ FileFree (void *object)
> {
> File *file = object;
>
> - if (file->fd == -1)
> - return 1;
> - if (FileClose ((Value) file) != FileBlocked)
> + if (file->fd == -1 || FileClose ((Value) file) != FileBlocked)
> + {
> + FileChainFree (file->input);
> + file->input = NULL;
> + FileChainFree (file->output);
> + file->output = NULL;
> return 1;
> + }
> return 0;
> }
>
> @@ -613,30 +639,6 @@ FileResetFd (int fd)
> #endif
> }
>
> -static void
> -FileChainMark (void *object)
> -{
> - FileChainPtr chain = object;
> -
> - MemReference (chain->next);
> -}
> -
> -DataType FileChainType = { FileChainMark, 0, "FileChainType" };
> -
> -static FileChainPtr
> -NewFileChain (FileChainPtr next, int size)
> -{
> - ENTER ();
> - FileChainPtr ret;
> -
> - ret = MemAllocate (&FileChainType, sizeof (FileChain) + size);
> - ret->next = next;
> - ret->size = size;
> - ret->used = 0;
> - ret->ptr = 0;
> - RETURN (ret);
> -}
> -
> Value
> FileCreate (int fd, int flags)
> {
> @@ -893,7 +895,7 @@ FileStringRead (char *string, int len)
>
> file = NewFile (-1);
> file->file.flags |= FileString|FileReadable;
> - file->file.input = NewFileChain (0, len);
> + file->file.input = FileChainAlloc (0, len);
> memcpy (FileBuffer (file->file.input), string, len);
> file->file.input->used = len;
> RETURN (file);
> @@ -1009,7 +1011,7 @@ FileInput (Value file)
> EXIT ();
> return FileEOF;
> }
> - file->file.input = NewFileChain (0, FileBufferSize);
> + file->file.input = FileChainAlloc (NULL, FileBufferSize);
> }
> ic = file->file.input;
> for (;;)
> @@ -1022,7 +1024,12 @@ FileInput (Value file)
> else
> {
> if (ic->next)
> - ic = ic->next;
> + {
> + file->file.input = ic->next;
> + ic->next = NULL;
> + FileChainFree (ic);
> + ic = file->file.input;
> + }
> else if (file->file.flags & FileString)
> {
> file->file.flags |= FileEnd;
> @@ -1084,7 +1091,7 @@ FileUnput (Value file, unsigned char c)
> ic = file->file.input;
> if (!ic || ic->ptr == 0)
> {
> - ic = file->file.input = NewFileChain (file->file.input, FileBufferSize);
> + ic = file->file.input = FileChainAlloc (file->file.input, FileBufferSize);
> ic->ptr = ic->used = ic->size;
> }
> FileBuffer(ic)[--ic->ptr] = c;
> @@ -1175,6 +1182,8 @@ FileFlush (Value file, Bool block)
> ic->used = ic->ptr = 0;
> break;
> }
> + else
> + FileChainFree (ic);
> *prev = 0;
> }
> }
> @@ -1214,7 +1223,7 @@ FileOutput (Value file, char c)
> }
> ic = file->file.output;
> if (!ic)
> - ic = file->file.output = NewFileChain (0, FileBufferSize);
> + ic = file->file.output = FileChainAlloc (0, FileBufferSize);
> if (ic->used == ic->size)
> {
> if (FileFlush (file, False) == FileError)
> @@ -1224,7 +1233,7 @@ FileOutput (Value file, char c)
> }
> ic = file->file.output;
> if (ic->used == ic->size)
> - ic = file->file.output = NewFileChain (file->file.output, FileBufferSize);
> + ic = file->file.output = FileChainAlloc (file->file.output, FileBufferSize);
> }
> ic = file->file.output;
> FileBuffer(ic)[ic->used++] = c;
> diff --git a/value.h b/value.h
> index c941011..e94428f 100644
> --- a/value.h
> +++ b/value.h
> @@ -625,7 +625,6 @@ typedef struct _array {
> #define ArrayValueSet(a,i,v) (BoxValueSet(ArrayValueBox(a,i),ArrayValueElt(a,i), v))
>
> typedef struct _io_chain {
> - DataType *data;
> struct _io_chain *next;
> int size;
> int used;
> commit 8e3690cea5da54d83e6fd6d26c073c1c4d8ae403
> Author: Keith Packard <keithp at koto.keithp.com>
> Date: Tue Oct 2 01:16:05 2007 -0700
>
> Extend Ctype namespace to latin-1.
>
> This should be extended to all of unicode, but that's a huge amount of data.
>
> diff --git a/ctype.5c b/ctype.5c
> index 88dd1df..a595452 100644
> --- a/ctype.5c
> +++ b/ctype.5c
> @@ -16,8 +16,8 @@ namespace Ctype {
> return ch >= 0 && ch <= 127;
> }
>
> - /* The characteristic vector of sets of ASCII chars. */
> - public typedef bool[128] charset;
> + /* The characteristic vector of sets of Latin-1 chars. */
> + public typedef bool[256] charset;
>
> public charset make_charset(bool(int) cfun)
> /*
> @@ -25,7 +25,7 @@ namespace Ctype {
> */
> {
> charset result;
> - for (int i = 0; i < 128; i++)
> + for (int i = 0; i < dim(result); i++)
> result[i] = cfun(i);
> return result;
> }
> @@ -35,7 +35,7 @@ namespace Ctype {
> * Test whether a particular char is in a charset.
> */
> {
> - return isascii(ch) && v[ch];
> + return ch >= 0 && ch < dim(v) && v[ch];
> }
>
>
> @@ -51,7 +51,8 @@ namespace Ctype {
> */
> {
> static bool cfun(int ch) {
> - return ch >= 'A' && ch <= 'Z';
> + return (ch >= 'A' && ch <= 'Z' ||
> + ch >= 'Ã' && ch <= 'Ã');
> }
> static charset v = make_charset(cfun);
> return member(v, ch);
> @@ -63,7 +64,8 @@ namespace Ctype {
> */
> {
> static bool cfun(int ch) {
> - return ch >= 'a' && ch <= 'z';
> + return (ch >= 'a' && ch <= 'z' ||
> + ch >= 'à ' && ch <= 'þ');
> }
> static charset v = make_charset(cfun);
> return member(v, ch);
> @@ -107,7 +109,8 @@ namespace Ctype {
> */
> {
> static bool cfun(int ch) {
> - return ch > ' ' && ch < 127;
> + return (ch > ' ' && ch < 127 ||
> + ch >= 'Ã' && ch <= 'þ');
> }
> static charset v = make_charset(cfun);
> return member(v, ch);
> @@ -119,7 +122,8 @@ namespace Ctype {
> */
> {
> static bool cfun(int ch) {
> - return ch >= ' ' && ch < 127;
> + return (ch >= ' ' && ch < 127 ||
> + ch >= 'Ã' && ch <= 'þ');
> }
> static charset v = make_charset(cfun);
> return member(v, ch);
> commit 52c9ae4e5c476f6b202b49de3840c7ffdd0e02d8
> Author: Keith Packard <keithp at koto.keithp.com>
> Date: Tue Oct 2 01:15:16 2007 -0700
>
> Flush file output on exit call.
>
> Use of the built-in exit function should flush all file I/O, just as if the
> program terminated by returning to the top level at EOF.
>
> diff --git a/builtin-toplevel.c b/builtin-toplevel.c
> index 36f854c..6ef745b 100644
> --- a/builtin-toplevel.c
> +++ b/builtin-toplevel.c
> @@ -422,6 +422,7 @@ do_exit (Value av)
> if (aborting)
> RETURN (Void);
> IoFini ();
> + FileFini ();
> exit (code);
> RETURN (Void);
> }
>
> --===============1547860296==
> Content-Type: text/plain; charset="us-ascii"
> MIME-Version: 1.0
> Content-Transfer-Encoding: 7bit
> Content-Disposition: inline
>
> _______________________________________________
> Nickle mailing list
> Nickle at nickle.org
> http://nickle.org/mailman/listinfo/nickle
>
> --===============1547860296==--
More information about the Nickle
mailing list