Module Name: src
Committed By: pooka
Date: Thu May 2 21:35:19 UTC 2013
Modified Files:
src/lib/librumpuser: rumpuser.3 rumpuser_pth.c
src/sys/rump/include/rump: rumpuser.h
src/sys/rump/librump/rumpkern: locks.c
Log Message:
Push rwlock upgrade and downgrade into the hypervisor where there's
at least a chance to implement them with minimal fuss.
To generate a diff of this commit:
cvs rdiff -u -r1.6 -r1.7 src/lib/librumpuser/rumpuser.3
cvs rdiff -u -r1.24 -r1.25 src/lib/librumpuser/rumpuser_pth.c
cvs rdiff -u -r1.101 -r1.102 src/sys/rump/include/rump/rumpuser.h
cvs rdiff -u -r1.62 -r1.63 src/sys/rump/librump/rumpkern/locks.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/lib/librumpuser/rumpuser.3
diff -u src/lib/librumpuser/rumpuser.3:1.6 src/lib/librumpuser/rumpuser.3:1.7
--- src/lib/librumpuser/rumpuser.3:1.6 Thu May 2 19:14:59 2013
+++ src/lib/librumpuser/rumpuser.3 Thu May 2 21:35:19 2013
@@ -1,4 +1,4 @@
-.\" $NetBSD: rumpuser.3,v 1.6 2013/05/02 19:14:59 pooka Exp $
+.\" $NetBSD: rumpuser.3,v 1.7 2013/05/02 21:35:19 pooka Exp $
.\"
.\" Copyright (c) 2013 Antti Kantee. All rights reserved.
.\"
@@ -561,30 +561,38 @@ will never be called for that particular
.Fn rumpuser_rw_init "struct rumpuser_rw **rwp"
.Pp
.Ft void
-.Fn rumpuser_rw_enter "struct rumpuser_rw *rw" "int writelock"
+.Fn rumpuser_rw_enter "struct rumpuser_rw *rw" "const enum rumprwlock lk"
.Pp
.Ft int
-.Fn rumpuser_rw_tryenter "struct rumpuser_rw *rw" "int writelock"
+.Fn rumpuser_rw_tryenter "struct rumpuser_rw *rw" "const enum rumprwlock lk"
.Pp
-.Ft void
-.Fn rumpuser_rw_exit "struct rumpuser_rw *rw"
+.Ft int
+.Fn rumpuser_rw_tryupgrade "struct rumpuser_rw *rw"
.Pp
.Ft void
-.Fn rumpuser_rw_destroy "struct rumpuser_rw *rw"
+.Fn rumpuser_rw_downgrade "struct rumpuser_rw *rw"
.Pp
.Ft void
-.Fn rumpuser_rw_held "struct rumpuser_rw *rw" "int *heldp"
+.Fn rumpuser_rw_exit "struct rumpuser_rw *rw"
.Pp
.Ft void
-.Fn rumpuser_rw_rdheld "struct rumpuser_rw *rw" "int *heldp"
+.Fn rumpuser_rw_destroy "struct rumpuser_rw *rw"
.Pp
.Ft void
-.Fn rumpuser_rw_wrheld "struct rumpuser_rw *rw" "int *heldp"
-.Pp
-Read/write locks acquire an exclusive version of the lock if the
-.Fa writelock
-parameter is non-zero and a shared lock otherwise.
+.Fo rumpuser_rw_held
+.Fa "struct rumpuser_rw *rw" "const enum rumprwlock lk" "int *heldp"
+.Fc
.Pp
+Read/write locks provide either shared or exclusive locking.
+The possible values for
+.Fa lk
+are
+.Dv RUMPUSER_RW_READER
+and
+.Dv RUMPUSER_RW_WRITER .
+Upgrading means trying to migrate from an already owned shared
+lock to an exclusive lock and downgrading means migrating from
+an already owned exclusive lock to a shared lock.
.Pp
.Ft void
.Fn rumpuser_cv_init "struct rumpuser_cv **cvp"
Index: src/lib/librumpuser/rumpuser_pth.c
diff -u src/lib/librumpuser/rumpuser_pth.c:1.24 src/lib/librumpuser/rumpuser_pth.c:1.25
--- src/lib/librumpuser/rumpuser_pth.c:1.24 Thu May 2 20:33:54 2013
+++ src/lib/librumpuser/rumpuser_pth.c Thu May 2 21:35:19 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: rumpuser_pth.c,v 1.24 2013/05/02 20:33:54 pooka Exp $ */
+/* $NetBSD: rumpuser_pth.c,v 1.25 2013/05/02 21:35:19 pooka Exp $ */
/*
* Copyright (c) 2007-2010 Antti Kantee. All Rights Reserved.
@@ -28,7 +28,7 @@
#include "rumpuser_port.h"
#if !defined(lint)
-__RCSID("$NetBSD: rumpuser_pth.c,v 1.24 2013/05/02 20:33:54 pooka Exp $");
+__RCSID("$NetBSD: rumpuser_pth.c,v 1.25 2013/05/02 21:35:19 pooka Exp $");
#endif /* !lint */
#include <sys/queue.h>
@@ -286,40 +286,72 @@ rumpuser_rw_init(struct rumpuser_rw **rw
}
void
-rumpuser_rw_enter(struct rumpuser_rw *rw, int iswrite)
+rumpuser_rw_enter(struct rumpuser_rw *rw, const enum rumprwlock lk)
{
- if (iswrite) {
+ switch (lk) {
+ case RUMPUSER_RW_WRITER:
if (pthread_rwlock_trywrlock(&rw->pthrw) != 0)
KLOCK_WRAP(NOFAIL_ERRNO(
pthread_rwlock_wrlock(&rw->pthrw)));
RURW_SETWRITE(rw);
- } else {
+ break;
+ case RUMPUSER_RW_READER:
if (pthread_rwlock_tryrdlock(&rw->pthrw) != 0)
KLOCK_WRAP(NOFAIL_ERRNO(
pthread_rwlock_rdlock(&rw->pthrw)));
RURW_INCREAD(rw);
+ break;
}
}
int
-rumpuser_rw_tryenter(struct rumpuser_rw *rw, int iswrite)
+rumpuser_rw_tryenter(struct rumpuser_rw *rw, const enum rumprwlock lk)
{
int rv;
- if (iswrite) {
+ switch (lk) {
+ case RUMPUSER_RW_WRITER:
rv = pthread_rwlock_trywrlock(&rw->pthrw);
if (rv == 0)
RURW_SETWRITE(rw);
- } else {
+ break;
+ case RUMPUSER_RW_READER:
rv = pthread_rwlock_tryrdlock(&rw->pthrw);
if (rv == 0)
RURW_INCREAD(rw);
+ break;
+ default:
+ rv = EINVAL;
+ break;
}
ET(rv);
}
+int
+rumpuser_rw_tryupgrade(struct rumpuser_rw *rw)
+{
+
+ /* not supported by pthreads */
+ ET(EBUSY);
+}
+
+void
+rumpuser_rw_downgrade(struct rumpuser_rw *rw)
+{
+
+ /*
+ * I guess this is not strictly speaking correct,
+ * but the option is to provide a complete implementation
+ * of rwlocks here, or at least wrap acquiry in 1) lock
+ * 2) check if someone is downgrading. if not, we're done
+ * 3) unlock 4) yield 5) goto 1.
+ */
+ rumpuser_rw_exit(rw);
+ rumpuser_rw_enter(rw, RUMPUSER_RW_READER);
+}
+
void
rumpuser_rw_exit(struct rumpuser_rw *rw)
{
@@ -341,24 +373,17 @@ rumpuser_rw_destroy(struct rumpuser_rw *
}
void
-rumpuser_rw_held(struct rumpuser_rw *rw, int *rv)
-{
-
- *rv = rw->readers != 0;
-}
-
-void
-rumpuser_rw_rdheld(struct rumpuser_rw *rw, int *rv)
+rumpuser_rw_held(struct rumpuser_rw *rw, const enum rumprwlock lk, int *rv)
{
- *rv = RURW_HASREAD(rw);
-}
-
-void
-rumpuser_rw_wrheld(struct rumpuser_rw *rw, int *rv)
-{
-
- *rv = RURW_AMWRITER(rw);
+ switch (lk) {
+ case RUMPUSER_RW_WRITER:
+ *rv = RURW_AMWRITER(rw);
+ break;
+ case RUMPUSER_RW_READER:
+ *rv = RURW_HASREAD(rw);
+ break;
+ }
}
void
Index: src/sys/rump/include/rump/rumpuser.h
diff -u src/sys/rump/include/rump/rumpuser.h:1.101 src/sys/rump/include/rump/rumpuser.h:1.102
--- src/sys/rump/include/rump/rumpuser.h:1.101 Thu May 2 19:15:01 2013
+++ src/sys/rump/include/rump/rumpuser.h Thu May 2 21:35:19 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: rumpuser.h,v 1.101 2013/05/02 19:15:01 pooka Exp $ */
+/* $NetBSD: rumpuser.h,v 1.102 2013/05/02 21:35:19 pooka Exp $ */
/*
* Copyright (c) 2007-2013 Antti Kantee. All Rights Reserved.
@@ -180,14 +180,15 @@ void rumpuser_mutex_destroy(struct rumpu
void rumpuser_mutex_owner(struct rumpuser_mtx *, struct lwp **);
struct rumpuser_rw;
+enum rumprwlock { RUMPUSER_RW_READER, RUMPUSER_RW_WRITER };
void rumpuser_rw_init(struct rumpuser_rw **);
-void rumpuser_rw_enter(struct rumpuser_rw *, int);
-int rumpuser_rw_tryenter(struct rumpuser_rw *, int);
+void rumpuser_rw_enter(struct rumpuser_rw *, const enum rumprwlock);
+int rumpuser_rw_tryenter(struct rumpuser_rw *, const enum rumprwlock);
+int rumpuser_rw_tryupgrade(struct rumpuser_rw *);
+void rumpuser_rw_downgrade(struct rumpuser_rw *);
void rumpuser_rw_exit(struct rumpuser_rw *);
void rumpuser_rw_destroy(struct rumpuser_rw *);
-void rumpuser_rw_held(struct rumpuser_rw *, int *);
-void rumpuser_rw_rdheld(struct rumpuser_rw *, int *);
-void rumpuser_rw_wrheld(struct rumpuser_rw *, int *);
+void rumpuser_rw_held(struct rumpuser_rw *, const enum rumprwlock, int *);
struct rumpuser_cv;
void rumpuser_cv_init(struct rumpuser_cv **);
Index: src/sys/rump/librump/rumpkern/locks.c
diff -u src/sys/rump/librump/rumpkern/locks.c:1.62 src/sys/rump/librump/rumpkern/locks.c:1.63
--- src/sys/rump/librump/rumpkern/locks.c:1.62 Thu May 2 20:37:32 2013
+++ src/sys/rump/librump/rumpkern/locks.c Thu May 2 21:35:19 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: locks.c,v 1.62 2013/05/02 20:37:32 pooka Exp $ */
+/* $NetBSD: locks.c,v 1.63 2013/05/02 21:35:19 pooka Exp $ */
/*
* Copyright (c) 2007-2011 Antti Kantee. All Rights Reserved.
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: locks.c,v 1.62 2013/05/02 20:37:32 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: locks.c,v 1.63 2013/05/02 21:35:19 pooka Exp $");
#include <sys/param.h>
#include <sys/kmem.h>
@@ -187,6 +187,20 @@ mutex_owner(kmutex_t *mtx)
/* reader/writer locks */
+static enum rumprwlock
+krw2rumprw(const krw_t op)
+{
+
+ switch (op) {
+ case RW_READER:
+ return RUMPUSER_RW_READER;
+ case RW_WRITER:
+ return RUMPUSER_RW_WRITER;
+ default:
+ panic("unknown rwlock type");
+ }
+}
+
void
rw_init(krwlock_t *rw)
{
@@ -211,7 +225,7 @@ rw_enter(krwlock_t *rw, const krw_t op)
WANTLOCK(rw, op == RW_READER, false);
- rumpuser_rw_enter(RUMPRW(rw), op == RW_WRITER);
+ rumpuser_rw_enter(RUMPRW(rw), krw2rumprw(op));
LOCKED(rw, op == RW_READER);
}
@@ -220,7 +234,7 @@ rw_tryenter(krwlock_t *rw, const krw_t o
{
int error;
- error = rumpuser_rw_tryenter(RUMPRW(rw), op == RW_WRITER);
+ error = rumpuser_rw_tryenter(RUMPRW(rw), krw2rumprw(op));
if (error == 0) {
WANTLOCK(rw, op == RW_READER, true);
LOCKED(rw, op == RW_READER);
@@ -242,51 +256,53 @@ rw_exit(krwlock_t *rw)
rumpuser_rw_exit(RUMPRW(rw));
}
-/* always fails */
int
rw_tryupgrade(krwlock_t *rw)
{
+ int rv;
- return 0;
+ rv = rumpuser_rw_tryupgrade(RUMPRW(rw));
+ if (rv == 0) {
+ UNLOCKED(rw, 1);
+ WANTLOCK(rw, 0, true);
+ LOCKED(rw, 0);
+ }
+ return rv == 0;
}
void
rw_downgrade(krwlock_t *rw)
{
- /*
- * XXX HACK: How we can downgrade re lock in rump properly.
- */
- rw_exit(rw);
- rw_enter(rw, RW_READER);
- return;
+ rumpuser_rw_downgrade(RUMPRW(rw));
+ UNLOCKED(rw, 0);
+ WANTLOCK(rw, 1, false);
+ LOCKED(rw, 1);
}
int
-rw_write_held(krwlock_t *rw)
+rw_read_held(krwlock_t *rw)
{
int rv;
- rumpuser_rw_wrheld(RUMPRW(rw), &rv);
+ rumpuser_rw_held(RUMPRW(rw), RUMPUSER_RW_READER, &rv);
return rv;
}
int
-rw_read_held(krwlock_t *rw)
+rw_write_held(krwlock_t *rw)
{
int rv;
- rumpuser_rw_rdheld(RUMPRW(rw), &rv);
+ rumpuser_rw_held(RUMPRW(rw), RUMPUSER_RW_WRITER, &rv);
return rv;
}
int
rw_lock_held(krwlock_t *rw)
{
- int rv;
- rumpuser_rw_held(RUMPRW(rw), &rv);
- return rv;
+ return rw_read_held(rw) || rw_write_held(rw);
}
/* curriculum vitaes */