drop use of pthread_once in timer_create
authorRich Felker <dalias@aerifal.cx>
Wed, 14 Oct 2020 23:07:27 +0000 (19:07 -0400)
committerRich Felker <dalias@aerifal.cx>
Thu, 15 Oct 2020 00:27:12 +0000 (20:27 -0400)
this makes the code slightly smaller and eliminates timer_create from
relevance to possible future changes to multithreaded fork.

the barrier of a_store isn't technically needed here, but a_store is
used anyway for internal consistency of the memory model.

src/time/timer_create.c

index 2b1ea17..5ddfda2 100644 (file)
@@ -2,6 +2,7 @@
 #include <setjmp.h>
 #include <limits.h>
 #include "pthread_impl.h"
+#include "atomic.h"
 
 struct ksigevent {
        union sigval sigev_value;
@@ -32,14 +33,6 @@ static void cleanup_fromsig(void *p)
        longjmp(p, 1);
 }
 
-static void install_handler()
-{
-       struct sigaction sa = {
-               .sa_handler = SIG_DFL,
-       };
-       __libc_sigaction(SIGTIMER, &sa, 0);
-}
-
 static void *start(void *arg)
 {
        pthread_t self = __pthread_self();
@@ -66,7 +59,7 @@ static void *start(void *arg)
 
 int timer_create(clockid_t clk, struct sigevent *restrict evp, timer_t *restrict res)
 {
-       static pthread_once_t once = PTHREAD_ONCE_INIT;
+       volatile static int init = 0;
        pthread_t td;
        pthread_attr_t attr;
        int r;
@@ -90,7 +83,11 @@ int timer_create(clockid_t clk, struct sigevent *restrict evp, timer_t *restrict
                *res = (void *)(intptr_t)timerid;
                break;
        case SIGEV_THREAD:
-               pthread_once(&once, install_handler);
+               if (!init) {
+                       struct sigaction sa = { .sa_handler = SIG_DFL };
+                       __libc_sigaction(SIGTIMER, &sa, 0);
+                       a_store(&init, 1);
+               }
                if (evp->sigev_notify_attributes)
                        attr = *evp->sigev_notify_attributes;
                else