Gerbage collection as a library | | |
I've tried to implement some garbage collection library for see. Here is
an example of it's usage. Do you think that it is usefull at all and
deserve development?
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include "virlib.h"
void fclose_p (void *p);
void print (fp);
char *readline (fp);
int
main (int argc, char **argv)
{
FILE *fp;
begin_func ();
fp = fopen ("style.txt", "r");
add_destructor (fp, fclose_p);
print (fp);
end_func ();
return 0;
}
void
fclose_p (void *p)
{
fclose (p);
}
void
print (fp)
{
char *s;
int n;
begin_func ();
n = 0;
while ((s = readline (fp)) != NULL)
fprintf ("%4d%s", n++, s);
end_func ();
}
char *
readline (fp)
{
char *s, *t, *p;
int alen, llen;
begin_func ();
alen = 10;
s = malloc (alen);
if (s == NULL)
fail ("allocating buffer to read");
add_destructor (s, free);
p = s;
for (;;) {
t = fgets (p, alen, fp);
if (t == NULL) {
end_func ();
return NULL;
}
llen = strlen (p);
if (p[llen - 1] == '\n') {
mark_result (s);
end_func ();
return s;
}
llen = p - s;
t = realloc (s, alen * 2);
if (t == NULL)
fail ("allocating buffer to read");
mark_global (s); /* No need to destruct s */
s = t;
add_destructor (s, free);
p = s + llen;
}
} | | | | re: Gerbage collection as a library
In article <dr7taq$2g50$1@news.comcor-tv.ru>,
Victor Nazarov <vir@comtv.ru> wrote:[color=blue]
>I've tried to implement some garbage collection library for see. Here is
>an example of it's usage. Do you think that it is usefull at all and
>deserve development?[/color]
[code snipped]
I would suggest that you describe each of the library operations and
their purpose.
It appears from your code example that the user needs to manually
add_destructor) each item which is to be garbage collected,
and to mark_global() each item which is not to be garbage collected.
The user also appears to need to begin_func(), and appears to need
to end_func() at the end before returning from your routine.
The operation of mark_result() is not clear from your example --
does it sort of move the pointer's destruction time into the frame
above? But if it does then if you are returning a pointer through
multiple layers, you would have to know to mark_result() the pointer
at each layer. What is the user to do if the user wants to
return a structure or array that mixes items which are to be have
destructors run and items which are not to have destructors run?
It is not apparent from your example why it is that you do not
have two operations:
1) add_destructor() to record that an item will need to be garbage collected.
return value: an internal marker of the current garbage collection stack.
2) gc() to trigger a garbage collection. The argument to this would
be one of the values returned by add_destructor(), and gc() would
do the destruction of everything back to that marker.
There is no obvious need in your scheme for mark_global() since if
something is not marked for destruction then it simply wouldn't be
destroyed. (I do not have advice at the moment as to how to
handle values that are going to be returned.)
In my -opinion-, your present interface has too much manual work and
coding overhead, and would not become popular.
[color=blue]
>char *
>readline (fp)
>{
> char *s, *t, *p;
> int alen, llen;
>
> begin_func ();
> alen = 10;
> s = malloc (alen);
> if (s == NULL)
> fail ("allocating buffer to read");
> add_destructor (s, free);
>
> p = s;
> for (;;) {
> t = fgets (p, alen, fp);
> if (t == NULL) {
> end_func ();
> return NULL;
> }
>
> llen = strlen (p);
> if (p[llen - 1] == '\n') {
> mark_result (s);
> end_func ();
> return s;
> }
>
> llen = p - s;
> t = realloc (s, alen * 2);[/color]
After the realloc(), the former value of s is not certain
to be valid anymore. This implies that you would need an operation
which was "transfer the attributes associated with this pointer
to instead be associated with this other pointer".
[color=blue]
> if (t == NULL)
> fail ("allocating buffer to read");
> mark_global (s); /* No need to destruct s */[/color]
But the value of s is not valid anymore?? Unless this -is- your
way of saying, "remove the attributes that were associated with this
pointer" -- and then requiring the user to know what the attributes
were and to set them on the new pointer. It would be easier on
the user to have a realloc() wrapper that took care of these details.
[color=blue]
> s = t;
> add_destructor (s, free);
> p = s + llen;
> }
>}[/color]
--
"It is important to remember that when it comes to law, computers
never make copies, only human beings make copies. Computers are given
commands, not permission. Only people can be given permission."
-- Brad Templeton | | | | re: Gerbage collection as a library
Walter Roberson wrote:[color=blue]
> In article <dr7taq$2g50$1@news.comcor-tv.ru>,
> It appears from your code example that the user needs to manually
> add_destructor) each item which is to be garbage collected,
> and to mark_global() each item which is not to be garbage collected.[/color]
yes
[color=blue]
> The user also appears to need to begin_func(), and appears to need
> to end_func() at the end before returning from your routine.[/color]
yes
[color=blue]
> The operation of mark_result() is not clear from your example --
> does it sort of move the pointer's destruction time into the frame
> above?[/color]
yes
[color=blue]
> But if it does then if you are returning a pointer through
> multiple layers, you would have to know to mark_result() the pointer
> at each layer.[/color]
User must mark_result() every "object" that function returns. I think
it's not so difficult to know what are you returning.
[color=blue]
> What is the user to do if the user wants to
> return a structure or array that mixes items which are to be have
> destructors run and items which are not to have destructors run?[/color]
That's not solved yet. I think some routings should be written for
containers to implement their own resource managment. So if object is
added to an array it should be deleted when the array is deleted.
May be you can suggest something?
[color=blue]
> It is not apparent from your example why it is that you do not
> have two operations:
>
> 1) add_destructor() to record that an item will need to be garbage collected.
> return value: an internal marker of the current garbage collection stack.
>
> 2) gc() to trigger a garbage collection. The argument to this would
> be one of the values returned by add_destructor(), and gc() would
> do the destruction of everything back to that marker.[/color]
Hmm, it's impossible to implement it from user level, only compiler
level, isn't it? I'm just trying to add resource management to C, not
developing new language. There are Java and Caml after all.
[color=blue]
> There is no obvious need in your scheme for mark_global() since if
> something is not marked for destruction then it simply wouldn't be
> destroyed.[/color]
So it's used in the realloc example, i. e. "cancel managment of this
object, I'll do this manually".
[color=blue]
> (I do not have advice at the moment as to how to
> handle values that are going to be returned.)
>
>
> In my -opinion-, your present interface has too much manual work and
> coding overhead, and would not become popular.[/color]
My interface shouldn't be used every where. That was the part of the
design. The question is "are there cases when this library whould be
much better then manual resource managment? and how often is this?".
[color=blue]
> After the realloc(), the former value of s is not certain
> to be valid anymore. This implies that you would need an operation
> which was "transfer the attributes associated with this pointer
> to instead be associated with this other pointer".
>
>[color=green]
>> if (t == NULL)
>> fail ("allocating buffer to read");
>> mark_global (s); /* No need to destruct s */[/color]
>
>
> But the value of s is not valid anymore?? Unless this -is- your
> way of saying, "remove the attributes that were associated with this
> pointer" -- and then requiring the user to know what the attributes
> were and to set them on the new pointer.[/color]
Yes, that's what I've said.
[color=blue]
> It would be easier on
> the user to have a realloc() wrapper that took care of these details.[/color]
Yes, it would. |  | | | | /bytes/about
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 226,510 network members.
|