From owner-freebsd-arch@FreeBSD.ORG Wed Jun 9 18:35:43 2004 Return-Path: Delivered-To: freebsd-arch@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 4AA2016A4CE for ; Wed, 9 Jun 2004 18:35:43 +0000 (GMT) Received: from rwcrmhc11.comcast.net (rwcrmhc11.comcast.net [204.127.198.35]) by mx1.FreeBSD.org (Postfix) with ESMTP id 401D143D54 for ; Wed, 9 Jun 2004 18:35:43 +0000 (GMT) (envelope-from julian@elischer.org) Received: from interjet.elischer.org ([24.7.73.28]) by comcast.net (rwcrmhc11) with ESMTP id <200406091835400130097dhie>; Wed, 9 Jun 2004 18:35:41 +0000 Received: from localhost (localhost.elischer.org [127.0.0.1]) by InterJet.elischer.org (8.9.1a/8.9.1) with ESMTP id LAA59232 for ; Wed, 9 Jun 2004 11:35:42 -0700 (PDT) Date: Wed, 9 Jun 2004 11:35:40 -0700 (PDT) From: Julian Elischer To: arch@freebsd.org Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Subject: reference counting.. continued.. X-BeenThere: freebsd-arch@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Discussion related to FreeBSD architecture List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 09 Jun 2004 18:35:43 -0000 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.