mirror of git://git.musl-libc.org/musl
optimize cancellation enable/disable code
the goal is to be able to use pthread_setcancelstate internally in the implementation, whenever a function might want to use functions which are cancellation points but avoid becoming a cancellation point itself. i could have just used a separate internal function for temporarily inhibiting cancellation, but the solution in this commit is better because (1) it's one less implementation-specific detail in functions that need to use it, and (2) application code can also get the same benefit. previously, pthread_setcancelstate dependend on pthread_self, which would pull in unwanted thread setup overhead for non-threaded programs. now, it temporarily stores the state in the global libc struct if threads have not been initialized, and later moves it if needed. this way we can instead use __pthread_self, which has no dependencies and assumes that the thread register is already valid.
This commit is contained in:
parent
02eff258c6
commit
ebf82447be
|
@ -16,6 +16,7 @@ struct __libc {
|
||||||
volatile int threads_minus_1;
|
volatile int threads_minus_1;
|
||||||
int ofl_lock;
|
int ofl_lock;
|
||||||
FILE *ofl_head;
|
FILE *ofl_head;
|
||||||
|
int canceldisable;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ static int *errno_location()
|
||||||
|
|
||||||
static int init_main_thread()
|
static int init_main_thread()
|
||||||
{
|
{
|
||||||
|
main_thread.canceldisable = libc.canceldisable;
|
||||||
main_thread.tsd = (void **)__pthread_tsd_main;
|
main_thread.tsd = (void **)__pthread_tsd_main;
|
||||||
main_thread.self = &main_thread;
|
main_thread.self = &main_thread;
|
||||||
if (__set_thread_area(&main_thread) < 0)
|
if (__set_thread_area(&main_thread) < 0)
|
||||||
|
|
|
@ -2,9 +2,14 @@
|
||||||
|
|
||||||
int pthread_setcancelstate(int new, int *old)
|
int pthread_setcancelstate(int new, int *old)
|
||||||
{
|
{
|
||||||
struct pthread *self = pthread_self();
|
|
||||||
if (old) *old = self->canceldisable;
|
|
||||||
if (new > 1U) return EINVAL;
|
if (new > 1U) return EINVAL;
|
||||||
self->canceldisable = new;
|
if (libc.lock) {
|
||||||
|
struct pthread *self = __pthread_self();
|
||||||
|
if (old) *old = self->canceldisable;
|
||||||
|
self->canceldisable = new;
|
||||||
|
} else {
|
||||||
|
if (old) *old = libc.canceldisable;
|
||||||
|
libc.canceldisable = new;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
int pthread_setcanceltype(int new, int *old)
|
int pthread_setcanceltype(int new, int *old)
|
||||||
{
|
{
|
||||||
struct pthread *self = pthread_self();
|
struct pthread *self = pthread_self();
|
||||||
|
if (new > 1U) return EINVAL;
|
||||||
if (old) *old = self->cancelasync;
|
if (old) *old = self->cancelasync;
|
||||||
if ((unsigned)new > 1) return EINVAL;
|
|
||||||
self->cancelasync = new;
|
self->cancelasync = new;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue