Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 12 Dec 2000 17:00:43 -0500 (EST)
From:      Garrett Wollman <wollman@khavrinen.lcs.mit.edu>
To:        John Baldwin <jhb@FreeBSD.ORG>
Cc:        arch@FreeBSD.ORG
Subject:   Re: An opaque refcount type
Message-ID:  <200012122200.RAA53571@khavrinen.lcs.mit.edu>
In-Reply-To: <XFMail.001212130656.jhb@FreeBSD.org>
References:  <200012122100.QAA53113@khavrinen.lcs.mit.edu> <XFMail.001212130656.jhb@FreeBSD.org>

next in thread | previous in thread | raw e-mail | index | archive | help
<<On Tue, 12 Dec 2000 13:06:56 -0800 (PST), John Baldwin <jhb@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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200012122200.RAA53571>