From owner-freebsd-arch Tue Dec 12 14: 0:52 2000 From owner-freebsd-arch@FreeBSD.ORG Tue Dec 12 14:00:49 2000 Return-Path: Delivered-To: freebsd-arch@freebsd.org Received: from khavrinen.lcs.mit.edu (khavrinen.lcs.mit.edu [18.24.4.193]) by hub.freebsd.org (Postfix) with ESMTP id 2325F37B400; Tue, 12 Dec 2000 14:00:46 -0800 (PST) Received: (from wollman@localhost) by khavrinen.lcs.mit.edu (8.9.3/8.9.3) id RAA53571; Tue, 12 Dec 2000 17:00:43 -0500 (EST) (envelope-from wollman) Date: Tue, 12 Dec 2000 17:00:43 -0500 (EST) From: Garrett Wollman Message-Id: <200012122200.RAA53571@khavrinen.lcs.mit.edu> To: John Baldwin Cc: arch@FreeBSD.ORG Subject: Re: An opaque refcount type In-Reply-To: References: <200012122100.QAA53113@khavrinen.lcs.mit.edu> Sender: owner-freebsd-arch@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG < said: > It's opaque in the sense that a user doesn't know what it is inside > it. In order to include it in a data structure, the user must know what is inside it. That is the crux of the problem. We have already learned to our dismay how tangled messes of include files and other definitions can cause problems, and more importantly that having potentially-exported data structures depend on kernel compilation options. Here is an alternative formulation: #define DECLARE_REFCOUNT(prefix) \ int prefix ## _refcnt; \ struct refcount_bk * prefix ## _refcnt_bk; /* * Actually, don't use the macro above, but rather, declare your structure * as if it were expanded inline, so that your header file does not * depend on this one as a prerequisite. */ #ifdef INVARIANT_SUPPORT #define REFHOLD(count, bookkeeping) \ ((bookkeeping != 0) \ ? refcount_track(count, bookkeeping, 1) \ : atomic_increment(count)) \ #define REFDROP(count, bookkeeping) \ ((bookkeeping != 0) \ ? refcount_track(count, bookkeeping, -1); \ : atomic_decrement(count)) \ #else #define REFHOLD(count, bookkeeping) \ atomic_increment(count) #define REFDROP(count, bookkeeping) \ atomic_decrement(count) #endif #ifdef INVARIANTS struct refcount_bk *refcount_bk_init(int *countp); void refcount_bk_destroy(struct refcount_bk *bookkeeping); #else #define refcount_bk_init(countp) (struct refcount_bk *)0 #define refcount_bk_destroy(bk) /* nothing */ #endif /******* example of usage *******/ /* gronk.h */ struct gronk { /* insert real data for gronk structure */ int gronk_refcnt; struct refcount_bk *gronk_bk; }; /* gronk.c */ #include "gronk.h" #include "refcnt.h" void gronk_init(struct gronk *gronk) { /* insert real initialization */ gronk->gronk_refcnt = 0; /* or however many you want */ gronk->gronk_bk = refcount_bk_init(&gronk->gronk_refcnt); } void gronk_ref(struct gronk *gronk) { REFHOLD(gronk->gronk_refcnt, gronk->gronk_bk); } void gronk_rele(struct gronk *gronk) { if (REFDROP(gronk->gronk_refcnt, gronk->gronk_bk) == 1) gronk_free(gronk); } /************************************/ Obviously, this rouine requires the ability to allocate memory when creating the `refcount_bk' structures. This is not a serious problem. It also gives clients more flexibility with respect to determining which reference counts are checked, which may be useful for debugging. -GAWollman -- Garrett A. Wollman | O Siem / We are all family / O Siem / We're all the same wollman@lcs.mit.edu | O Siem / The fires of freedom Opinions not those of| Dance in the burning flame MIT, LCS, CRS, or NSA| - Susan Aglukark and Chad Irschick To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-arch" in the body of the message