| lh | 9ed821d | 2023-04-07 01:36:19 -0700 | [diff] [blame] | 1 | #include <errno.h> | 
|  | 2 | #include <pthread.h> | 
|  | 3 | #include <stdio.h> | 
|  | 4 | #include <stdlib.h> | 
|  | 5 | #include <unistd.h> | 
|  | 6 | #include <sys/wait.h> | 
|  | 7 |  | 
|  | 8 | #define NKEYS 100 | 
|  | 9 | static pthread_key_t keys[NKEYS]; | 
|  | 10 | static pthread_barrier_t b; | 
|  | 11 |  | 
|  | 12 |  | 
|  | 13 | static void * | 
|  | 14 | tf (void *arg) | 
|  | 15 | { | 
|  | 16 | void *res = NULL; | 
|  | 17 | for (int i = 0; i < NKEYS; ++i) | 
|  | 18 | { | 
|  | 19 | void *p = pthread_getspecific (keys[i]); | 
|  | 20 | pthread_setspecific (keys[i], (void *) 7); | 
|  | 21 | if (p != NULL) | 
|  | 22 | res = p; | 
|  | 23 | } | 
|  | 24 | if (arg != NULL) | 
|  | 25 | { | 
|  | 26 | pthread_barrier_wait (arg); | 
|  | 27 | pthread_barrier_wait (arg); | 
|  | 28 | } | 
|  | 29 | return res; | 
|  | 30 | } | 
|  | 31 |  | 
|  | 32 |  | 
|  | 33 | static int | 
|  | 34 | do_test (void) | 
|  | 35 | { | 
|  | 36 | pthread_barrier_init (&b, NULL, 2); | 
|  | 37 |  | 
|  | 38 | for (int i = 0; i < NKEYS; ++i) | 
|  | 39 | if (pthread_key_create (&keys[i], NULL) != 0) | 
|  | 40 | { | 
|  | 41 | puts ("cannot create keys"); | 
|  | 42 | return 1; | 
|  | 43 | } | 
|  | 44 |  | 
|  | 45 | pthread_t th; | 
|  | 46 | if (pthread_create (&th, NULL, tf, &b) != 0) | 
|  | 47 | { | 
|  | 48 | puts ("cannot create thread in parent"); | 
|  | 49 | return 1; | 
|  | 50 | } | 
|  | 51 |  | 
|  | 52 | pthread_barrier_wait (&b); | 
|  | 53 |  | 
|  | 54 | pid_t pid = fork (); | 
|  | 55 | if (pid == 0) | 
|  | 56 | { | 
|  | 57 | if (pthread_create (&th, NULL, tf, NULL) != 0) | 
|  | 58 | { | 
|  | 59 | puts ("cannot create thread in child"); | 
|  | 60 | exit (1); | 
|  | 61 | } | 
|  | 62 |  | 
|  | 63 | void *res; | 
|  | 64 | pthread_join (th, &res); | 
|  | 65 |  | 
|  | 66 | exit (res != NULL); | 
|  | 67 | } | 
|  | 68 | else if (pid == -1) | 
|  | 69 | { | 
|  | 70 | puts ("cannot create child process"); | 
|  | 71 | return 1; | 
|  | 72 | } | 
|  | 73 |  | 
|  | 74 | int s; | 
|  | 75 | if (TEMP_FAILURE_RETRY (waitpid (pid, &s, 0)) != pid) | 
|  | 76 | { | 
|  | 77 | puts ("failing to wait for child process"); | 
|  | 78 | return 1; | 
|  | 79 | } | 
|  | 80 |  | 
|  | 81 | pthread_barrier_wait (&b); | 
|  | 82 | pthread_join (th, NULL); | 
|  | 83 |  | 
|  | 84 | return !WIFEXITED (s) ? 2 : WEXITSTATUS (s); | 
|  | 85 | } | 
|  | 86 |  | 
|  | 87 |  | 
|  | 88 | #define TEST_FUNCTION do_test () | 
|  | 89 | #include "../test-skeleton.c" |