some feature test fixes for unistd.h
[musl] / src / thread / forkall.c
1 #if 0
2 #include "pthread_impl.h"
3 #include <setjmp.h>
4
5 struct thread {
6         struct thread *next;
7         pthread_t td;
8         jmp_buf jb;
9         void *tmp, *stack;
10 };
11
12 struct ctx {
13         struct thread *list;
14         pthread_t caller;
15         pid_t pid;
16         size_t cnt;
17         pthread_barrier_t barrier;
18 };
19
20 static void restart_thread(pthread_t self)
21 {
22         struct thread *t = self->start_arg;
23         self->start_arg = t->tmp;
24         self->pid = getpid();
25         longjmp(t->jb, 1);
26 }
27
28 static void do_forkall(void *p)
29 {
30         struct ctx *c = p, *volatile cv = c;
31         char tmpstack[2048];
32         struct thread *tp, t = {
33                 .td = __pthread_self(),
34                 .next = c->list,
35                 .stack = tmpstack+1024
36         };
37
38         if (t.td != c->caller) {
39                 c->cnt++;
40                 t.tmp = t.td->start_arg;
41                 t.td->start_arg = &t;
42                 if (setjmp(t.jb)) {
43                         c = cv;
44                         if (c->pid) return;
45                         pthread_barrier_wait(&c->barrier);
46                         return;
47                 }
48                 c->list = &t;
49                 __synccall_wait();
50                 return;
51         }
52         c->pid = syscall(SYS_fork);
53         if (c->pid) return;
54
55         pthread_barrier_init(&c->barrier, 0, c->cnt);
56         for (tp=c->list; tp; tp=tp->next)
57                 if (__uniclone(tp->stack, restart_thread, tp->td) < 0)
58                         _exit(127);
59         pthread_barrier_wait(&c->barrier);
60 }
61
62 pid_t forkall()
63 {
64         struct ctx c = { .caller = pthread_self() };
65         __synccall(do_forkall, &c);
66         return c.pid;
67 }
68 #endif