summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordavidxu <davidxu@FreeBSD.org>2008-06-09 01:14:10 +0000
committerdavidxu <davidxu@FreeBSD.org>2008-06-09 01:14:10 +0000
commitf4d6ff9c5e2c00dd44c3e39b44c0000351d91c6d (patch)
tree64448ccd5c1431710c5a1f4513a5128d2db5c444
parent7c70b8f716071ee1944fc97021c0857b385b755c (diff)
downloadFreeBSD-src-f4d6ff9c5e2c00dd44c3e39b44c0000351d91c6d.zip
FreeBSD-src-f4d6ff9c5e2c00dd44c3e39b44c0000351d91c6d.tar.gz
Make pthread_cleanup_push() and pthread_cleanup_pop() as a pair of macros,
use stack space to keep cleanup information, this eliminates overhead of calling malloc() and free() in thread library. Discussed on: thread@
-rw-r--r--include/pthread.h23
-rw-r--r--lib/libc/include/namespace.h2
-rw-r--r--lib/libc/include/un-namespace.h2
-rw-r--r--lib/libthr/pthread.map2
-rw-r--r--lib/libthr/thread/thr_clean.c55
-rw-r--r--lib/libthr/thread/thr_private.h15
6 files changed, 71 insertions, 28 deletions
diff --git a/include/pthread.h b/include/pthread.h
index 215b882..fad12b1 100644
--- a/include/pthread.h
+++ b/include/pthread.h
@@ -135,6 +135,10 @@ enum pthread_mutextype {
#define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_ERRORCHECK
+struct _pthread_cleanup_info {
+ __uintptr_t pthread_cleanup_pad[8];
+};
+
/*
* Thread function prototype definitions:
*/
@@ -162,8 +166,19 @@ int pthread_barrierattr_getpshared(const pthread_barrierattr_t *,
int *);
int pthread_barrierattr_init(pthread_barrierattr_t *);
int pthread_barrierattr_setpshared(pthread_barrierattr_t *, int);
-void pthread_cleanup_pop(int);
-void pthread_cleanup_push(void (*) (void *), void *);
+
+#define pthread_cleanup_push(cleanup_routine, cleanup_arg) \
+ { \
+ struct _pthread_cleanup_info __cleanup_info__; \
+ __pthread_cleanup_push_imp(cleanup_routine, cleanup_arg,\
+ &__cleanup_info__); \
+ {
+
+#define pthread_cleanup_pop(execute) \
+ } \
+ __pthread_cleanup_pop_imp(execute); \
+ }
+
int pthread_condattr_destroy(pthread_condattr_t *);
int pthread_condattr_getclock(const pthread_condattr_t *,
clockid_t *);
@@ -268,6 +283,10 @@ int pthread_setschedparam(pthread_t, int,
const struct sched_param *);
int pthread_getconcurrency(void);
int pthread_setconcurrency(int);
+
+void __pthread_cleanup_push_imp(void (*)(void *), void *,
+ struct _pthread_cleanup_info *);
+void __pthread_cleanup_pop_imp(int);
__END_DECLS
#endif
diff --git a/lib/libc/include/namespace.h b/lib/libc/include/namespace.h
index 22c3f64..a65b929 100644
--- a/lib/libc/include/namespace.h
+++ b/lib/libc/include/namespace.h
@@ -114,8 +114,6 @@
#define pthread_barrierattr_init _pthread_barrierattr_init
#define pthread_barrierattr_setpshared _pthread_barrierattr_setpshared
#define pthread_cancel _pthread_cancel
-#define pthread_cleanup_pop _pthread_cleanup_pop
-#define pthread_cleanup_push _pthread_cleanup_push
#define pthread_cond_broadcast _pthread_cond_broadcast
#define pthread_cond_destroy _pthread_cond_destroy
#define pthread_cond_init _pthread_cond_init
diff --git a/lib/libc/include/un-namespace.h b/lib/libc/include/un-namespace.h
index 64d1676..6b7f49a 100644
--- a/lib/libc/include/un-namespace.h
+++ b/lib/libc/include/un-namespace.h
@@ -95,8 +95,6 @@
#undef pthread_barrierattr_init
#undef pthread_barrierattr_setpshared
#undef pthread_cancel
-#undef pthread_cleanup_pop
-#undef pthread_cleanup_push
#undef pthread_cond_broadcast
#undef pthread_cond_destroy
#undef pthread_cond_init
diff --git a/lib/libthr/pthread.map b/lib/libthr/pthread.map
index 21a0135..79bbd4c 100644
--- a/lib/libthr/pthread.map
+++ b/lib/libthr/pthread.map
@@ -393,6 +393,8 @@ FBSDprivate_1.0 {
};
FBSD_1.1 {
+ __pthread_cleanup_pop_imp;
+ __pthread_cleanup_push_imp;
pthread_attr_getaffinity_np;
pthread_attr_setaffinity_np;
pthread_getaffinity_np;
diff --git a/lib/libthr/thread/thr_clean.c b/lib/libthr/thread/thr_clean.c
index 9922798..9cef930 100644
--- a/lib/libthr/thread/thr_clean.c
+++ b/lib/libthr/thread/thr_clean.c
@@ -38,38 +38,61 @@
#include "thr_private.h"
+#undef pthread_cleanup_push
+#undef pthread_cleanup_pop
+
+/* old binary compatible interfaces */
__weak_reference(_pthread_cleanup_push, pthread_cleanup_push);
__weak_reference(_pthread_cleanup_pop, pthread_cleanup_pop);
void
-_pthread_cleanup_push(void (*routine) (void *), void *routine_arg)
+__pthread_cleanup_push_imp(void (*routine)(void *), void *arg,
+ struct _pthread_cleanup_info *info)
{
struct pthread *curthread = _get_curthread();
- struct pthread_cleanup *new;
-
- if ((new = (struct pthread_cleanup *)
- malloc(sizeof(struct pthread_cleanup))) != NULL) {
- new->routine = routine;
- new->routine_arg = routine_arg;
- new->onstack = 0;
- new->next = curthread->cleanup;
+ struct pthread_cleanup *newbuf;
- curthread->cleanup = new;
- }
+ newbuf = (void *)info;
+ newbuf->routine = routine;
+ newbuf->routine_arg = arg;
+ newbuf->onheap = 0;
+ newbuf->prev = curthread->cleanup;
+ curthread->cleanup = newbuf;
}
void
-_pthread_cleanup_pop(int execute)
+__pthread_cleanup_pop_imp(int execute)
{
struct pthread *curthread = _get_curthread();
struct pthread_cleanup *old;
if ((old = curthread->cleanup) != NULL) {
- curthread->cleanup = old->next;
- if (execute) {
+ curthread->cleanup = old->prev;
+ if (execute)
old->routine(old->routine_arg);
- }
- if (old->onstack == 0)
+ if (old->onheap)
free(old);
}
}
+
+void
+_pthread_cleanup_push(void (*routine) (void *), void *arg)
+{
+ struct pthread *curthread = _get_curthread();
+ struct pthread_cleanup *newbuf;
+
+ if ((newbuf = (struct pthread_cleanup *)
+ malloc(sizeof(struct _pthread_cleanup_info))) != NULL) {
+ newbuf->routine = routine;
+ newbuf->routine_arg = arg;
+ newbuf->onheap = 1;
+ newbuf->prev = curthread->cleanup;
+ curthread->cleanup = newbuf;
+ }
+}
+
+void
+_pthread_cleanup_pop(int execute)
+{
+ __pthread_cleanup_pop_imp(execute);
+}
diff --git a/lib/libthr/thread/thr_private.h b/lib/libthr/thread/thr_private.h
index e84ba23..e336b2c 100644
--- a/lib/libthr/thread/thr_private.h
+++ b/lib/libthr/thread/thr_private.h
@@ -176,10 +176,10 @@ struct pthread_spinlock {
* Cleanup definitions.
*/
struct pthread_cleanup {
- struct pthread_cleanup *next;
- void (*routine)(void *args);
+ struct pthread_cleanup *prev;
+ void (*routine)(void *);
void *routine_arg;
- int onstack;
+ int onheap;
};
#define THR_CLEANUP_PUSH(td, func, arg) { \
@@ -187,12 +187,12 @@ struct pthread_cleanup {
\
__cup.routine = func; \
__cup.routine_arg = arg; \
- __cup.onstack = 1; \
- __cup.next = (td)->cleanup; \
+ __cup.onheap = 0; \
+ __cup.prev = (td)->cleanup; \
(td)->cleanup = &__cup;
#define THR_CLEANUP_POP(td, exec) \
- (td)->cleanup = __cup.next; \
+ (td)->cleanup = __cup.prev; \
if ((exec) != 0) \
__cup.routine(__cup.routine_arg); \
}
@@ -661,6 +661,9 @@ void _thread_bp_create(void);
void _thread_bp_death(void);
int _sched_yield(void);
+void _pthread_cleanup_push(void (*)(void *), void *);
+void _pthread_cleanup_pop(int);
+
/* #include <fcntl.h> */
#ifdef _SYS_FCNTL_H_
int __sys_fcntl(int, int, ...);
OpenPOWER on IntegriCloud