From owner-freebsd-arch Mon Nov 12 15:50:49 2001 Delivered-To: freebsd-arch@freebsd.org Received: from apollo.backplane.com (apollo.backplane.com [216.240.41.2]) by hub.freebsd.org (Postfix) with ESMTP id 0960137B416; Mon, 12 Nov 2001 15:50:46 -0800 (PST) Received: (from dillon@localhost) by apollo.backplane.com (8.11.6/8.9.1) id fACNojg07127; Mon, 12 Nov 2001 15:50:45 -0800 (PST) (envelope-from dillon) Date: Mon, 12 Nov 2001 15:50:45 -0800 (PST) From: Matthew Dillon Message-Id: <200111122350.fACNojg07127@apollo.backplane.com> To: John Baldwin Cc: Terry Lambert , Robert Watson , freebsd-arch@FreeBSD.org Subject: Re: cur{thread/proc}, or not. References: Sender: owner-freebsd-arch@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG You want to be very careful not to bloat the concept. We already have severe bloatage in the mutex code and that has led to a lot of unnecessary complexity. A huge amount, in fact. We have so many types of mutexes it makes my head spin and I'm not very happy about it. Forget about 'shared' verses 'exclusive'. A reference count is a reference count, that's all. If you keep the concept simple you can implement more functionality horizontally rather then implementing more complexity vertically. For example, consider this API for pool mutexes. /* * obtain related pool mutex */ void pool_mtx_lock(void *ptr); { } /* * release related pool mutex. */ void pool_mtx_unlock(void *ptr) { } Now consider how this could be combined with, say, the zalloc() and zfree() code. Consider how it could be combined with the refcount code. It might even be possible to remove the stable-storage requirement. Consider a vnode verses its underlying VM object. Consider this: vp = vnode ... we already have a ref count on the vp. while ((object = vp->v_object) != NULL) { pool_mtx_lock(object) if (vp->v_object == object) break; pool_mtx_unlock(object) } /* object guarenteed to be associated with vnode */ ++object->ref_cnt; pool_mtx_unlock(object); ... continue working on object Structural overhead: 0 bytes Parallelism: high Now consider how this might be combined with the refcnt pool code: CODE PIECE 1: vp = vnode ... we already have a ref count on the vp. while ((object = vp->v_object) != NULL) { pool_mtx_lock(&object->ref_cnt); if (vp->v_object == object) break; pool_mtx_unlock(&object->ref_cnt) } /* object guarenteed to be associated with vnode */ ++object->ref_cnt; pool_mtx_unlock(&object->ref_cnt); CODE PIECE 2 (compatible with CODE PIECE 1): /* object is a known good object that will not be going away soon */ refcnt_bump(&object->ref_cnt); ... use object ... refcnt_drop(&object->ref_cnt); And there you have it. An utterly simple API of four routines (refcnt routines and pool routines), with a huge amount of capability. -Matt To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-arch" in the body of the message