Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src Push rwlock upgrade and downgrade into the hypervisor where ...
details: https://anonhg.NetBSD.org/src/rev/0d1002f7928d
branches: trunk
changeset: 786589:0d1002f7928d
user: pooka <pooka%NetBSD.org@localhost>
date: Thu May 02 21:35:19 2013 +0000
description:
Push rwlock upgrade and downgrade into the hypervisor where there's
at least a chance to implement them with minimal fuss.
diffstat:
lib/librumpuser/rumpuser.3 | 36 +++++++++++-------
lib/librumpuser/rumpuser_pth.c | 73 ++++++++++++++++++++++++++------------
sys/rump/include/rump/rumpuser.h | 13 +++---
sys/rump/librump/rumpkern/locks.c | 66 +++++++++++++++++++++-------------
4 files changed, 119 insertions(+), 69 deletions(-)
diffs (truncated from 353 to 300 lines):
diff -r 8045e6cf0025 -r 0d1002f7928d lib/librumpuser/rumpuser.3
--- a/lib/librumpuser/rumpuser.3 Thu May 02 21:11:18 2013 +0000
+++ b/lib/librumpuser/rumpuser.3 Thu May 02 21:35:19 2013 +0000
@@ -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,10 +561,16 @@
.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 int
+.Fn rumpuser_rw_tryupgrade "struct rumpuser_rw *rw"
+.Pp
+.Ft void
+.Fn rumpuser_rw_downgrade "struct rumpuser_rw *rw"
.Pp
.Ft void
.Fn rumpuser_rw_exit "struct rumpuser_rw *rw"
@@ -573,18 +579,20 @@
.Fn rumpuser_rw_destroy "struct rumpuser_rw *rw"
.Pp
.Ft void
-.Fn rumpuser_rw_held "struct rumpuser_rw *rw" "int *heldp"
-.Pp
-.Ft void
-.Fn rumpuser_rw_rdheld "struct rumpuser_rw *rw" "int *heldp"
+.Fo rumpuser_rw_held
+.Fa "struct rumpuser_rw *rw" "const enum rumprwlock lk" "int *heldp"
+.Fc
.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.
-.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"
diff -r 8045e6cf0025 -r 0d1002f7928d lib/librumpuser/rumpuser_pth.c
--- a/lib/librumpuser/rumpuser_pth.c Thu May 02 21:11:18 2013 +0000
+++ b/lib/librumpuser/rumpuser_pth.c Thu May 02 21:35:19 2013 +0000
@@ -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 @@
}
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 @@
}
void
-rumpuser_rw_held(struct rumpuser_rw *rw, int *rv)
+rumpuser_rw_held(struct rumpuser_rw *rw, const enum rumprwlock lk, int *rv)
{
- *rv = rw->readers != 0;
-}
-
-void
-rumpuser_rw_rdheld(struct rumpuser_rw *rw, 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
diff -r 8045e6cf0025 -r 0d1002f7928d sys/rump/include/rump/rumpuser.h
--- a/sys/rump/include/rump/rumpuser.h Thu May 02 21:11:18 2013 +0000
+++ b/sys/rump/include/rump/rumpuser.h Thu May 02 21:35:19 2013 +0000
@@ -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_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 **);
diff -r 8045e6cf0025 -r 0d1002f7928d sys/rump/librump/rumpkern/locks.c
--- a/sys/rump/librump/rumpkern/locks.c Thu May 02 21:11:18 2013 +0000
+++ b/sys/rump/librump/rumpkern/locks.c Thu May 02 21:35:19 2013 +0000
@@ -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 @@
/* 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 @@
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 @@
{
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,24 +256,37 @@
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)
Home |
Main Index |
Thread Index |
Old Index