signal, SIGUSR1. The function isn't important, since the signal is sent only to interrupt the call to sigsuspend in suspend_signal_handler.

¦ susp.c part1 signal-catching functions

1 #include <pthread.h>

2 #include <signal.h>

3 #include 'errors.h'

4

5 #define THREAD_COUNT 20

6 #define ITERATIONS 40000

*A semaphore, as described later in Section 6.6.6, would provide cleaner, and somewhat safer, synchronization. The thd_suspend would call sem_wait on a semaphore with an inltial value of 0, and the signal-catching function would call sem_post to wake it.

7

8 unsigned long thread_count = THREAD_COUNT;

9 unsigned long iterations = ITERATIONS;

10 pthread_mutex_t the_mutex = PTHREAD_MUTEX_INITIALIZER;

11 pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;

12 volatile int sentinel = 0;

13 pthread_once_t once = PTHREAD_ONCE_INIT;

14 pthread_t *array = NULL, null_pthread = {0};

15 int bottom = 0;

16 int inited = 0; 17

18 /*

19 * Handle SIGUSR1 in the target thread, to suspend it until

20 * receiving SIGUSR2 (resume).

21 */

22 void

23 suspend_signal_handler (int sig)

24 {

25  sigset_t signal_set;

26

27 /*

28 * Block all signals except SIGUSR2 while suspended.

29 */

30  sigfillset (&signal_set);

31  sigdelset (&signal_set, SIGUSR2);

32  sentinel = 1;

33  sigsuspend (&signal_set);

34

35 /*

36 * Once I'm here, I've been resumed, and the resume signal

37 * handler has been run to completion.

38 */

39  return;

40 }

41

42 /*

43 * Handle SIGUSR2 in the target thread, to resume it. Note that

44 * the signal handler does nothing. It exists only because we need

45 * to cause sigsuspend() to return.

46 */

47 void

48 resume_signal_handler (int sig)

49 {

50  return;

51 }

The suspend_init_routine function dynamically initializes the suspend/ resume package when the first call to thd_suspend is made. It is actually called indirectly by pthread_once.

15-16 It allocates an initial array of thread identifiers, which is used to record the identifiers of all threads that have been suspended. This array is used to ensure that multiple calls to thd_suspend have no additional effect on the target thread, and that calling thd_continue for a thread that is not suspended has no effect.

21-35 It sets up signal actions for the SIGUSR1 and SIGUSR2 signals, which will be used, respectively, to suspend and resume threads.

¦ susp.c part 2 initialization

1 /*

2 * Dynamically initialize the 'suspend package' when first used

3 * (called by pthread_once).

4 */

5 void

6 suspend_init_routine (void)

7 {

8  int status;

9  struct sigaction sigusrl, sigusr2;

10

11 /*

12 * Allocate the suspended threads array. This array is used

13 * to guarentee idempotency

14 */

15  bottom = 10;

16  array = (pthread_t*) calloc (bottom, sizeof (pthread_t)); 17

18 /*

19 * Install the signal handlers for suspend/resume.

20 */

21  sigusrl.sa_flags = 0;

22  sigusrl.sa_handler = suspend_signal_handler; 23

24  sigemptyset (&sigusrl.sa_mask);

25  sigusr2.sa_flags = 0;

26  sigusr2.sa_handler = resume_signal_handler;

27  sigusr2.sa_mask = sigusrl.sa_mask;

28

29  status = sigaction (SIGUSR1, &sigusrl, NULL);

30  if (status == -1)

31  errno_abort ('Installing suspend handler'); 32

33  status = sigaction (SIGUSR2, &sigusr2, NULL);

34  if (status == -1)

35  errno_abort ('Installing resume handler');

36

37  inited = 1;

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату