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_ */