diff options
author | davidxu <davidxu@FreeBSD.org> | 2008-06-09 01:14:10 +0000 |
---|---|---|
committer | davidxu <davidxu@FreeBSD.org> | 2008-06-09 01:14:10 +0000 |
commit | f4d6ff9c5e2c00dd44c3e39b44c0000351d91c6d (patch) | |
tree | 64448ccd5c1431710c5a1f4513a5128d2db5c444 /lib | |
parent | 7c70b8f716071ee1944fc97021c0857b385b755c (diff) | |
download | FreeBSD-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.h | 2 | ||||
-rw-r--r-- | lib/libc/include/un-namespace.h | 2 | ||||
-rw-r--r-- | lib/libthr/pthread.map | 2 | ||||
-rw-r--r-- | lib/libthr/thread/thr_clean.c | 55 | ||||
-rw-r--r-- | lib/libthr/thread/thr_private.h | 15 |
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, ...); |