reference counting.. continued..

Julian Elischer julian at elischer.org
Wed Jun 9 18:35:43 GMT 2004


There are several goals that need to be kept in mind.

 * Operations should be quick.. 
 * Atomic operations can be slow in some architectures.
 * the last free may need to occur at an inconvenient time. 
   (in sched-lock or an interrupt routine).
 * There may need to be more than one kind of schedlock,
   for different cases, though I'd hope that they'd have the same 
   methods.. 
    (A reference count scheme that doesn't have to ever consider the
    fact that the object may be freed in an interrupt handler
    might be considereably smaller/quicker than one that needs to
    take that possibility into account.	)

Here's an API I mentionned once before.. I'm only showing this as an
example to start discussion...
it doesn't cover everything we'd need.. 

For example how would you do deferred free?


------------------quoted old email------------------

I have seen and liked 
a refcount API which was (from memory something like):

void * refcnt_add(offsetof(struct obj, refcnt), void ** object_p)

which takes a pointer to the object pointer you are copying, and 
atomically increments it and returns the contents of the pointer.
If the contents of the pointer are NULL, then it returns NULL
and doesn't increment anything..

The reference decrement atomically reduced the reference count and 
zapped the pointer, and retunred a copy of the pointer if
the reference count had gone to 0 (or NULL if not).

So usage was:
struct xx *globalpointer;   /* has its own owner somewhere */

        mypointer = refcnt_add(offsetof(xx, refcnt), globalptr)
        if (mypointer == NULL) {
                printf("didn't find an object\n"
                return (-1);

        }
        manipulate(mypointer)
        if ((tmppointer = refcnt_drop(&mypointer, &globalpointer))) {
                free(tmppointer);
        }



someone else who owns the globalpointer reference might might in
the meanwhile do:

if ((tmppointer = refcnt_drop(globalpointer->refcnt, &globalpointer))) {
        free(tmppointer);
}

and you were guaranteed to get a predictable result.




More information about the freebsd-arch mailing list