Module Name:    src
Committed By:   ad
Date:           Sun Apr 19 08:36:04 UTC 2009

Modified Files:
        src/sys/kern: kern_rwlock.c
        src/sys/sys: rwlock.h

Log Message:
Add rw_obj_*() functions to mirror the existing mutex functions.
Proposed on tech-kern quite some time ago.


To generate a diff of this commit:
cvs rdiff -u -r1.28 -r1.29 src/sys/kern/kern_rwlock.c
cvs rdiff -u -r1.6 -r1.7 src/sys/sys/rwlock.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/kern_rwlock.c
diff -u src/sys/kern/kern_rwlock.c:1.28 src/sys/kern/kern_rwlock.c:1.29
--- src/sys/kern/kern_rwlock.c:1.28	Tue Jul 29 16:13:39 2008
+++ src/sys/kern/kern_rwlock.c	Sun Apr 19 08:36:04 2009
@@ -1,7 +1,7 @@
-/*	$NetBSD: kern_rwlock.c,v 1.28 2008/07/29 16:13:39 thorpej Exp $	*/
+/*	$NetBSD: kern_rwlock.c,v 1.29 2009/04/19 08:36:04 ad Exp $	*/
 
 /*-
- * Copyright (c) 2002, 2006, 2007, 2008 The NetBSD Foundation, Inc.
+ * Copyright (c) 2002, 2006, 2007, 2008, 2009 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -38,7 +38,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_rwlock.c,v 1.28 2008/07/29 16:13:39 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_rwlock.c,v 1.29 2009/04/19 08:36:04 ad Exp $");
 
 #define	__RWLOCK_PRIVATE
 
@@ -161,6 +161,18 @@
 	rw_owner,
 };
 
+/* Mutex cache */
+#define	RW_OBJ_MAGIC	0x85d3c85d
+struct krwobj {
+	krwlock_t	ro_lock;
+	u_int		ro_magic;
+	u_int		ro_refcnt;
+};
+
+static int	rw_obj_ctor(void *, void *, int);
+
+static pool_cache_t	rw_obj_cache;
+
 /*
  * rw_dump:
  *
@@ -775,3 +787,88 @@
 
 	return (void *)(owner & RW_THREAD);
 }
+
+/*
+ * rw_obj_init:
+ *
+ *	Initialize the rw object store.
+ */
+void
+rw_obj_init(void)
+{
+
+	rw_obj_cache = pool_cache_init(sizeof(struct krwobj),
+	    coherency_unit, 0, 0, "rwlock", NULL, IPL_NONE, rw_obj_ctor,
+	    NULL, NULL);
+}
+
+/*
+ * rw_obj_ctor:
+ *
+ *	Initialize a new lock for the cache.
+ */
+static int
+rw_obj_ctor(void *arg, void *obj, int flags)
+{
+	struct krwobj * ro = obj;
+
+	ro->ro_magic = RW_OBJ_MAGIC;
+
+	return 0;
+}
+
+/*
+ * rw_obj_alloc:
+ *
+ *	Allocate a single lock object.
+ */
+krwlock_t *
+rw_obj_alloc(void)
+{
+	struct krwobj *ro;
+
+	ro = pool_cache_get(rw_obj_cache, PR_WAITOK);
+	rw_init(&ro->ro_lock);
+	ro->ro_refcnt = 1;
+
+	return (krwlock_t *)ro;
+}
+
+/*
+ * rw_obj_hold:
+ *
+ *	Add a single reference to a lock object.  A reference to the object
+ *	must already be held, and must be held across this call.
+ */
+void
+rw_obj_hold(krwlock_t *lock)
+{
+	struct krwobj *ro = (struct krwobj *)lock;
+
+	KASSERT(ro->ro_magic == RW_OBJ_MAGIC);
+	KASSERT(ro->ro_refcnt > 0);
+
+	atomic_inc_uint(&ro->ro_refcnt);
+}
+
+/*
+ * rw_obj_free:
+ *
+ *	Drop a reference from a lock object.  If the last reference is being
+ *	dropped, free the object and return true.  Otherwise, return false.
+ */
+bool
+rw_obj_free(krwlock_t *lock)
+{
+	struct krwobj *ro = (struct krwobj *)lock;
+
+	KASSERT(ro->ro_magic == RW_OBJ_MAGIC);
+	KASSERT(ro->ro_refcnt > 0);
+
+	if (atomic_dec_uint_nv(&ro->ro_refcnt) > 0) {
+		return false;
+	}
+	rw_destroy(&ro->ro_lock);
+	pool_cache_put(rw_obj_cache, ro);
+	return true;
+}

Index: src/sys/sys/rwlock.h
diff -u src/sys/sys/rwlock.h:1.6 src/sys/sys/rwlock.h:1.7
--- src/sys/sys/rwlock.h:1.6	Mon Apr 28 20:24:11 2008
+++ src/sys/sys/rwlock.h	Sun Apr 19 08:36:04 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: rwlock.h,v 1.6 2008/04/28 20:24:11 martin Exp $	*/
+/*	$NetBSD: rwlock.h,v 1.7 2009/04/19 08:36:04 ad Exp $	*/
 
 /*-
  * Copyright (c) 2002, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -107,6 +107,11 @@
 void	rw_enter(krwlock_t *, const krw_t);
 void	rw_exit(krwlock_t *);
 
+void	rw_obj_init(void);
+krwlock_t *rw_obj_alloc(void);
+void	rw_obj_hold(krwlock_t *);
+bool	rw_obj_free(krwlock_t *);
+
 #endif	/* _KERNEL */
 
 #endif /* _SYS_RWLOCK_H_ */

Reply via email to