summaryrefslogtreecommitdiffstats
path: root/lib/libpthread
diff options
context:
space:
mode:
authordeischen <deischen@FreeBSD.org>2003-11-04 20:01:38 +0000
committerdeischen <deischen@FreeBSD.org>2003-11-04 20:01:38 +0000
commit573b8090444db7cfee8d60b937cc6d39632c8bbc (patch)
tree2bcd2f3311b99d5ee4ad7786a416cfc8523178aa /lib/libpthread
parent3153a078d837c38f52c0c09ceadc066067332073 (diff)
downloadFreeBSD-src-573b8090444db7cfee8d60b937cc6d39632c8bbc.zip
FreeBSD-src-573b8090444db7cfee8d60b937cc6d39632c8bbc.tar.gz
Add the ability to reinitialize libpthread's internal FIFO-queueing
locks. Reviewed by: davidxu
Diffstat (limited to 'lib/libpthread')
-rw-r--r--lib/libpthread/sys/lock.c63
-rw-r--r--lib/libpthread/sys/lock.h9
2 files changed, 57 insertions, 15 deletions
diff --git a/lib/libpthread/sys/lock.c b/lib/libpthread/sys/lock.c
index 543487b..e65b552 100644
--- a/lib/libpthread/sys/lock.c
+++ b/lib/libpthread/sys/lock.c
@@ -45,7 +45,6 @@
void
_lock_destroy(struct lock *lck)
{
-
if ((lck != NULL) && (lck->l_head != NULL)) {
free(lck->l_head);
lck->l_head = NULL;
@@ -57,7 +56,6 @@ int
_lock_init(struct lock *lck, enum lock_type ltype,
lock_handler_t *waitfunc, lock_handler_t *wakeupfunc)
{
-
if (lck == NULL)
return (-1);
else if ((lck->l_head = malloc(sizeof(struct lockreq))) == NULL)
@@ -76,9 +74,26 @@ _lock_init(struct lock *lck, enum lock_type ltype,
}
int
-_lockuser_init(struct lockuser *lu, void *priv)
+_lock_reinit(struct lock *lck, enum lock_type ltype,
+ lock_handler_t *waitfunc, lock_handler_t *wakeupfunc)
{
+ if (lck == NULL)
+ return (-1);
+ else if (lck->l_head == NULL)
+ return (_lock_init(lck, ltype, waitfunc, wakeupfunc));
+ else {
+ lck->l_head->lr_locked = 0;
+ lck->l_head->lr_watcher = NULL;
+ lck->l_head->lr_owner = NULL;
+ lck->l_head->lr_active = 1;
+ lck->l_tail = lck->l_head;
+ }
+ return (0);
+}
+int
+_lockuser_init(struct lockuser *lu, void *priv)
+{
if (lu == NULL)
return (-1);
else if ((lu->lu_myreq == NULL) &&
@@ -97,10 +112,36 @@ _lockuser_init(struct lockuser *lu, void *priv)
return (0);
}
+int
+_lockuser_reinit(struct lockuser *lu, void *priv)
+{
+ if (lu == NULL)
+ return (-1);
+ /*
+ * All lockusers keep their watch request and drop their
+ * own (lu_myreq) request. Their own request is either
+ * some other lockuser's watch request or is the head of
+ * the lock.
+ */
+ lu->lu_myreq = lu->lu_watchreq;
+ if (lu->lu_myreq == NULL)
+ return (_lockuser_init(lu, priv));
+ else {
+ lu->lu_myreq->lr_locked = 1;
+ lu->lu_myreq->lr_watcher = NULL;
+ lu->lu_myreq->lr_owner = lu;
+ lu->lu_myreq->lr_active = 0;
+ lu->lu_watchreq = NULL;
+ lu->lu_priority = 0;
+ lu->lu_private = priv;
+ lu->lu_private2 = NULL;
+ }
+ return (0);
+}
+
void
_lockuser_destroy(struct lockuser *lu)
{
-
if ((lu != NULL) && (lu->lu_myreq != NULL))
free(lu->lu_myreq);
}
@@ -124,21 +165,19 @@ _lock_acquire(struct lock *lck, struct lockuser *lu, int prio)
if (lck == NULL || lu == NULL || lck->l_head == NULL)
return;
#endif
- if ((lck->l_type & LCK_PRIORITY) == 0)
- atomic_swap_ptr(&lck->l_head, lu->lu_myreq, &lu->lu_watchreq);
- else {
+ if ((lck->l_type & LCK_PRIORITY) != 0) {
LCK_ASSERT(lu->lu_myreq->lr_locked == 1);
LCK_ASSERT(lu->lu_myreq->lr_watcher == NULL);
LCK_ASSERT(lu->lu_myreq->lr_owner == lu);
LCK_ASSERT(lu->lu_watchreq == NULL);
lu->lu_priority = prio;
- /*
- * Atomically swap the head of the lock request with
- * this request.
- */
- atomic_swap_ptr(&lck->l_head, lu->lu_myreq, &lu->lu_watchreq);
}
+ /*
+ * Atomically swap the head of the lock request with
+ * this request.
+ */
+ atomic_swap_ptr(&lck->l_head, lu->lu_myreq, &lu->lu_watchreq);
if (lu->lu_watchreq->lr_locked != 0) {
atomic_store_rel_ptr(&lu->lu_watchreq->lr_watcher, lu);
diff --git a/lib/libpthread/sys/lock.h b/lib/libpthread/sys/lock.h
index 917ca63..6102a0b 100644
--- a/lib/libpthread/sys/lock.h
+++ b/lib/libpthread/sys/lock.h
@@ -79,14 +79,17 @@ struct lockuser {
#define _LCK_SET_PRIVATE2(lu, p) (lu)->lu_private2 = (void *)(p)
#define _LCK_GET_PRIVATE2(lu) (lu)->lu_private2
+void _lock_acquire(struct lock *, struct lockuser *, int);
void _lock_destroy(struct lock *);
+void _lock_grant(struct lock *, struct lockuser *);
int _lock_init(struct lock *, enum lock_type,
lock_handler_t *, lock_handler_t *);
+int _lock_reinit(struct lock *, enum lock_type,
+ lock_handler_t *, lock_handler_t *);
+void _lock_release(struct lock *, struct lockuser *);
int _lockuser_init(struct lockuser *lu, void *priv);
void _lockuser_destroy(struct lockuser *lu);
+int _lockuser_reinit(struct lockuser *lu, void *priv);
void _lockuser_setactive(struct lockuser *lu, int active);
-void _lock_acquire(struct lock *, struct lockuser *, int);
-void _lock_release(struct lock *, struct lockuser *);
-void _lock_grant(struct lock *, struct lockuser *);
#endif
OpenPOWER on IntegriCloud