tech-userlevel archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: Moving pthread_(cond|mutex) to libc
On Tue, Jan 22, 2013 at 02:28:36PM +0000, Emmanuel Dreyfus wrote:
> Right, I understand better now. Here is a secodn attempt:
> http://ftp.espci.fr/shadow/manu/pthread.patch
No comment? I doubt there are no objections to this be committed.
I guess the move from pthread_cond_wait_nothread to __libc_cond_timedwait
is not that smart, as it introduces a dependency on libc version into
libpthread. That is unwanted, right?
Here is it agiain posted inline.
Index: libpthread/pthread_cond.c
===================================================================
RCS file: /cvsroot/src/lib/libpthread/pthread_cond.c,v
retrieving revision 1.58
diff -U 4 -r1.58 pthread_cond.c
--- libpthread/pthread_cond.c 3 Nov 2012 03:10:50 -0000 1.58
+++ libpthread/pthread_cond.c 22 Jan 2013 14:23:33 -0000
@@ -54,16 +54,12 @@
#include <stdlib.h>
#include "pthread.h"
#include "pthread_int.h"
-
-int _sys___nanosleep50(const struct timespec *, struct timespec *);
+#include "../libc/thread-stub/thread-stub.h"
extern int pthread__started;
-static int pthread_cond_wait_nothread(pthread_t, pthread_mutex_t *,
- pthread_cond_t *, const struct timespec *);
-
int _pthread_cond_has_waiters_np(pthread_cond_t *);
__weak_alias(pthread_cond_has_waiters_np,_pthread_cond_has_waiters_np)
@@ -136,9 +132,9 @@
self = pthread__self();
/* Just hang out for a while if threads aren't running yet. */
if (__predict_false(pthread__started == 0)) {
- return pthread_cond_wait_nothread(self, mutex, cond, abstime);
+ return __libc_cond_timedwait(cond, mutex, abstime);
}
if (__predict_false(self->pt_cancel)) {
pthread__cancelled();
}
@@ -362,39 +358,4 @@
return 0;
}
-/* Utility routine to hang out for a while if threads haven't started yet. */
-static int
-pthread_cond_wait_nothread(pthread_t self, pthread_mutex_t *mutex,
- pthread_cond_t *cond, const struct timespec *abstime)
-{
- struct timespec now, diff;
- int retval;
-
- if (abstime == NULL) {
- diff.tv_sec = 99999999;
- diff.tv_nsec = 0;
- } else {
- clockid_t clck = cond->ptc_private ?
- *(clockid_t *)cond->ptc_private : CLOCK_REALTIME;
- clock_gettime(clck, &now);
- if (timespeccmp(abstime, &now, <))
- timespecclear(&diff);
- else
- timespecsub(abstime, &now, &diff);
- }
-
- do {
- pthread__testcancel(self);
- pthread_mutex_unlock(mutex);
- retval = _sys___nanosleep50(&diff, NULL);
- pthread_mutex_lock(mutex);
- } while (abstime == NULL && retval == 0);
- pthread__testcancel(self);
-
- if (retval == 0)
- return ETIMEDOUT;
- else
- /* spurious wakeup */
- return 0;
-}
Index: libpthread/pthread_mutex.c
===================================================================
RCS file: /cvsroot/src/lib/libpthread/pthread_mutex.c,v
retrieving revision 1.54
diff -U 4 -r1.54 pthread_mutex.c
--- libpthread/pthread_mutex.c 16 Aug 2012 04:49:47 -0000 1.54
+++ libpthread/pthread_mutex.c 22 Jan 2013 14:23:34 -0000
@@ -60,11 +60,12 @@
#include <stdio.h>
#include "pthread.h"
#include "pthread_int.h"
+#include "../libc/thread-stub/thread-stub.h"
#define MUTEX_WAITERS_BIT ((uintptr_t)0x01)
-#define MUTEX_RECURSIVE_BIT ((uintptr_t)0x02)
+#define MUTEX_RECURSIVE_BIT __LIBC_MUTEX_RECURSIVE_BIT /*
0x02 */
#define MUTEX_DEFERRED_BIT ((uintptr_t)0x04)
#define MUTEX_THREAD ((uintptr_t)-16L)
#define MUTEX_HAS_WAITERS(x) ((uintptr_t)(x) &
MUTEX_WAITERS_BIT)
Index: libpthread/pthread_queue.h
===================================================================
RCS file: /cvsroot/src/lib/libpthread/pthread_queue.h,v
retrieving revision 1.5
diff -U 4 -r1.5 pthread_queue.h
--- libpthread/pthread_queue.h 5 Oct 2009 23:33:48 -0000 1.5
+++ libpthread/pthread_queue.h 22 Jan 2013 14:23:34 -0000
@@ -31,8 +31,10 @@
#ifndef _LIB_PTHREAD_QUEUE_H
#define _LIB_PTHREAD_QUEUE_H
+#include "../libc/thread-stub/thread-stub.h"
+
/*
* Definition of a queue interface for the pthread library.
* Style modeled on the sys/queue.h macros; implementation taken from
* the tail queue, with the added property of static initializability
@@ -60,12 +62,9 @@
/*
* Queue functions.
*/
-#define PTQ_INIT(head) do {
\
- (head)->ptqh_first = NULL; \
- (head)->ptqh_last = &(head)->ptqh_first; \
-} while (/*CONSTCOND*/0)
+#define PTQ_INIT(head) __LIBC_PTQ_INIT(head)
#define PTQ_INSERT_HEAD(head, elm, field) do {
\
if (((elm)->field.ptqe_next = (head)->ptqh_first) != NULL) \
(head)->ptqh_first->field.ptqe_prev = \
Index: libc/thread-stub/thread-stub.c
===================================================================
RCS file: /cvsroot/src/lib/libc/thread-stub/thread-stub.c,v
retrieving revision 1.22
diff -U 4 -r1.22 thread-stub.c
--- libc/thread-stub/thread-stub.c 16 Sep 2011 16:05:59 -0000 1.22
+++ libc/thread-stub/thread-stub.c 22 Jan 2013 14:23:37 -0000
@@ -44,14 +44,19 @@
#define __LIBC_THREAD_STUBS
#include "namespace.h"
#include "reentrant.h"
+#include "thread-stub.h"
#include <errno.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
+#include <machine/lock.h>
+
+int _sys___nanosleep50(const struct timespec *, struct timespec *);
+
extern int __isthreaded;
#define DIE() (void)raise(SIGABRT)
@@ -83,66 +88,105 @@
/* mutexes */
int __libc_mutex_init_stub(mutex_t *, const mutexattr_t *);
-int __libc_mutex_catchall_stub(mutex_t *);
+int __libc_mutex_lock_stub(mutex_t *);
+int __libc_mutex_unlock_stub(mutex_t *);
+int __libc_mutex_destroy_stub(mutex_t *);
__weak_alias(__libc_mutex_init,__libc_mutex_init_stub)
-__weak_alias(__libc_mutex_lock,__libc_mutex_catchall_stub)
-__weak_alias(__libc_mutex_trylock,__libc_mutex_catchall_stub)
-__weak_alias(__libc_mutex_unlock,__libc_mutex_catchall_stub)
-__weak_alias(__libc_mutex_destroy,__libc_mutex_catchall_stub)
+__weak_alias(__libc_mutex_lock,__libc_mutex_lock_stub)
+__weak_alias(__libc_mutex_trylock,__libc_mutex_lock_stub)
+__weak_alias(__libc_mutex_unlock,__libc_mutex_unlock_stub)
+__weak_alias(__libc_mutex_destroy,__libc_mutex_destroy_stub)
-int __libc_mutexattr_catchall_stub(mutexattr_t *);
+int __libc_mutexattr_init_stub(mutexattr_t *);
int __libc_mutexattr_settype_stub(mutexattr_t *, int);
+int __libc_mutexattr_destroy_stub(mutexattr_t *);
-__weak_alias(__libc_mutexattr_init,__libc_mutexattr_catchall_stub)
-__weak_alias(__libc_mutexattr_destroy,__libc_mutexattr_catchall_stub)
+__weak_alias(__libc_mutexattr_init,__libc_mutexattr_init_stub)
+__weak_alias(__libc_mutexattr_destroy,__libc_mutexattr_destroy_stub)
__weak_alias(__libc_mutexattr_settype,__libc_mutexattr_settype_stub)
int
-__libc_mutex_init_stub(mutex_t *m, const mutexattr_t *a)
+__libc_mutex_init_stub(mutex_t *ptm, const mutexattr_t *attr)
{
- /* LINTED deliberate lack of effect */
- (void)m;
- /* LINTED deliberate lack of effect */
- (void)a;
+ intptr_t type;
- CHECK_NOT_THREADED();
+ if (attr == NULL)
+ type = PTHREAD_MUTEX_NORMAL;
+ else
+ type = (intptr_t)attr->ptma_private;
+
+ switch (type) {
+ case PTHREAD_MUTEX_ERRORCHECK:
+ ptm->ptm_owner = NULL;
+ break;
+ case PTHREAD_MUTEX_RECURSIVE:
+ ptm->ptm_owner = (void *)__LIBC_MUTEX_RECURSIVE_BIT;
+ break;
+ default:
+ ptm->ptm_owner = NULL;
+ break;
+ }
- return (0);
+ ptm->ptm_magic = _PT_MUTEX_MAGIC;
+ ptm->ptm_waiters = NULL;
+ ptm->ptm_recursed = 0;
+
+ return 0;
}
int
-__libc_mutex_catchall_stub(mutex_t *m)
+__libc_mutex_destroy_stub(mutex_t *ptm)
{
- /* LINTED deliberate lack of effect */
- (void)m;
+ ptm->ptm_magic = _PT_MUTEX_DEAD;
+ return 0;
+}
- CHECK_NOT_THREADED();
+int
+__libc_mutex_lock_stub(mutex_t *ptm)
+{
+ ptm->ptm_owner = (thr_t) -1;
+ return 0;
+}
- return (0);
+int
+__libc_mutex_unlock_stub(mutex_t *ptm)
+{
+ ptm->ptm_owner = NULL;
+ return 0;
}
int
__libc_mutexattr_settype_stub(mutexattr_t *ma, int type)
{
- /* LINTED deliberate lack of effect */
- (void)ma;
- /* LINTED deliberate lack of effect */
- (void)type;
+ switch (type) {
+ case PTHREAD_MUTEX_NORMAL:
+ case PTHREAD_MUTEX_ERRORCHECK:
+ case PTHREAD_MUTEX_RECURSIVE:
+ ma->ptma_private = (void *)(intptr_t)type;
+ return 0;
+ default:
+ return EINVAL;
+ }
+}
+
+int
+__libc_mutexattr_init_stub(mutexattr_t *ma)
+{
+ ma->ptma_magic = _PT_MUTEXATTR_MAGIC;
+ ma->ptma_private = (void *)PTHREAD_MUTEX_DEFAULT;
+ return 0;
- return (0);
}
+
int
-__libc_mutexattr_catchall_stub(mutexattr_t *ma)
+__libc_mutexattr_destroy_stub(mutexattr_t *ma)
{
/* LINTED deliberate lack of effect */
(void)ma;
-
- CHECK_NOT_THREADED();
-
return (0);
}
/* condition variables */
@@ -151,55 +195,81 @@
int __libc_cond_wait_stub(cond_t *, mutex_t *);
int __libc_cond_timedwait_stub(cond_t *, mutex_t *,
const struct timespec *);
int __libc_cond_catchall_stub(cond_t *);
+int __libc_cond_destroy_stub(cond_t *);
__weak_alias(__libc_cond_init,__libc_cond_init_stub)
__weak_alias(__libc_cond_signal,__libc_cond_catchall_stub)
__weak_alias(__libc_cond_broadcast,__libc_cond_catchall_stub)
__weak_alias(__libc_cond_wait,__libc_cond_wait_stub)
__weak_alias(__libc_cond_timedwait,__libc_cond_timedwait_stub)
-__weak_alias(__libc_cond_destroy,__libc_cond_catchall_stub)
+__weak_alias(__libc_cond_destroy,__libc_cond_destroy_stub)
int
-__libc_cond_init_stub(cond_t *c, const condattr_t *a)
+__libc_cond_init_stub(cond_t *cond, const condattr_t *attr)
{
- /* LINTED deliberate lack of effect */
- (void)c;
- /* LINTED deliberate lack of effect */
- (void)a;
-
- CHECK_NOT_THREADED();
-
+ cond->ptc_magic = _PT_COND_MAGIC;
+ __cpu_simple_lock_init(&cond->ptc_lock);
+ __LIBC_PTQ_INIT(&cond->ptc_waiters);
+ cond->ptc_mutex = NULL;
+ if (attr && attr->ptca_private) {
+ cond->ptc_private = malloc(sizeof(clockid_t));
+ if (cond->ptc_private == NULL)
+ return errno;
+ *(clockid_t *)cond->ptc_private =
+ *(clockid_t *)attr->ptca_private;
+ } else
+ cond->ptc_private = NULL;
return (0);
}
int
-__libc_cond_wait_stub(cond_t *c, mutex_t *m)
+__libc_cond_wait_stub(cond_t *cond, mutex_t *mutex)
{
- /* LINTED deliberate lack of effect */
- (void)c;
- /* LINTED deliberate lack of effect */
- (void)m;
-
- CHECK_NOT_THREADED();
-
- return (0);
+ return __libc_cond_timedwait_stub(cond, mutex, NULL);
}
int
-__libc_cond_timedwait_stub(cond_t *c, mutex_t *m, const struct timespec *t)
+__libc_cond_timedwait_stub(cond_t *cond, mutex_t *mutex,
+ const struct timespec *abstime)
{
+ struct timespec now, diff;
+ int retval;
+
/* LINTED deliberate lack of effect */
- (void)c;
- /* LINTED deliberate lack of effect */
- (void)m;
- /* LINTED deliberate lack of effect */
- (void)t;
+ (void)mutex;
- CHECK_NOT_THREADED();
+ if (abstime == NULL) {
+ diff.tv_sec = 99999999;
+ diff.tv_nsec = 0;
+ } else {
+ clockid_t clck = cond->ptc_private ?
+ *(clockid_t *)cond->ptc_private : CLOCK_REALTIME;
+ clock_gettime(clck, &now);
+ if (timespeccmp(abstime, &now, <))
+ timespecclear(&diff);
+ else
+ timespecsub(abstime, &now, &diff);
+ }
- return (0);
+ do {
+ retval = _sys___nanosleep50(&diff, NULL);
+ } while (abstime == NULL && retval == 0);
+
+ if (retval == 0)
+ return ETIMEDOUT;
+ else
+ /* spurious wakeup */
+ return 0;
+}
+
+int
+__libc_cond_destroy_stub(cond_t *cond)
+{
+ cond->ptc_magic = _PT_COND_DEAD;
+ free(cond->ptc_private);
+ return 0;
}
int
__libc_cond_catchall_stub(cond_t *c)
@@ -213,9 +283,8 @@
}
/* read-write locks */
-
int __libc_rwlock_init_stub(rwlock_t *, rwlockattr_t *);
int __libc_rwlock_catchall_stub(rwlock_t *);
__weak_alias(__libc_rwlock_init,__libc_rwlock_init_stub)
--- libc/thread-stub/thread-stub.h.orig 2013-01-22 15:12:04.000000000 +0100
+++ libc/thread-stub/thread-stub.h 2013-01-22 15:07:52.000000000 +0100
@@ -0,0 +1,49 @@
+/* $NetBSD$ */
+
+/*-
+ * Copyright (c) 2001, 2003, 2006, 2007, 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Nathan J. Williams, by Jason R. Thorpe, and by Andrew Doran.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/time.h>
+#include <pthread_types.h>
+
+#define __LIBC_MUTEX_RECURSIVE_BIT ((uintptr_t)0x02)
+
+#define __LIBC_PTQ_INIT(head) do { \
+ (head)->ptqh_first = NULL; \
+ (head)->ptqh_last = &(head)->ptqh_first; \
+} while (/*CONSTCOND*/0)
+
+#ifndef cond_t
+#define cond_t pthread_cond_t
+#endif
+#ifndef mutex_t
+#define mutex_t pthread_mutex_t
+#endif
+
+int __libc_cond_timedwait(cond_t *, mutex_t *, const struct timespec *);
--
Emmanuel Dreyfus
manu%netbsd.org@localhost
Home |
Main Index |
Thread Index |
Old Index