summaryrefslogtreecommitdiffstats
path: root/lib
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 /lib
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@
Diffstat (limited to 'lib')
-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
5 files changed, 50 insertions, 26 deletions
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