Refcounting?

Ulf Ekström uekstrom at gmail.com
Thu Dec 30 16:15:33 EST 2004


Hi,

> > I added a check for double calls to refcount() on the same object,
> > if REFCOUNT_DEBUG is defined. It found a bug in bird.c where you use
> > refcount(). Actually all sprites are automatically
> > refcounted, so you never have to use refcount() when dealing with
> > them, only ref() and deref().
> 
> Ok.  I removed the refcounting from bird and added an option for the
> debugging to the Makefile (on by default).

Ok. It has some overhead, but not much.
 
[..]

> > > There's one strange thing in bonus.c:
> > > - You changed sprite_kill(s) to refkill(s) and when I looked into
> > >   sprite_kill() function, that indeed only calls refkill().  My
> > > question is: - Does sprite now get the MSG_KILL always when it's
> > > destroyed?
> >
> > It should send MSG_KILL indeed. I wonder if it does though.. I don't
> > have the code on this machine, but I will check.
> 
> sprite_kill() doesn't do anything else except refkill().  refkill() doesn't
> know anything about sprites...

When you call refcount() you give it a function to use when free'ing the object.
So in sprite_create() there is a line 

s = refcount(type->create_sprite(),type->free_sprite);

which means that type->free_sprite will be evaluated on s when the refcount
reaches zero. This is not exactly like killing, since it is evaluated
_after_ everyone
has released their references, not at the moment of the killing.

> > >   The reason why I ask is that the sprite should deref the referenced
> > >   sprite before dying...  See bonus_free() and bonus_sigget() in the
> > >   new sprites/bonus.c.

The dereferencing should be done in bonus_free(). The only exception is that
bonus_free() with _only_ be called when the refcount reaches zero. It has to be
like that because it's very likely that malloc() gives the same memory
area back on
the next call. Since we are identifying objects (dead and alive) with
their memory
location all references to the dead object must be gone before we
create a new one.
This is fine almost always, except when we want some action to happen
immediately
after we kill the sprite (such as the creation of smoke etc). As a
rule all references should
be gone after one game frame, but if we need some action in the same
frame this must
be implemented as a response to MSG_KILL. However, you must _not_ call
bonus_free()
directly there, only refkill(the_sprite_itself).

> Do you mean that the sprite_kill function would be removed from the sprite
> struct and replaced with handling of the MSG_KILL function?

It should be removed, and replaced by refkill. Using only MSG_KILL is
an option, but
I think refkill is fine.
 
> If sprite creation does refcount automatically, then killing sprite should
> call deref (or refkill?) which also frees the sprite I think.  I guess
> MSG_KILL handler should then do that... If sprite has some extra allocations
> it needs to free them before doing deref(), right?

We should use refkill (MSG_KILL should also use refkill), and then the
extra allocations
are free'd by sprite_type.free_sprite, which is called when all
references to the sprite are gone (and they will be released after the
killing if everything is working as it should).

Ulf



More information about the airstrike mailing list