38  return;

39 }

9-40 The thd_suspend function suspends a thread, and returns when that thread has ceased to execute user code. It first ensures that the suspend/resume package is initialized by calling pthread_once. Under protection of a mutex, it searches for the target thread's identifier in the array of suspended thread identifiers. If the thread is already suspended, thd_suspend returns successfully.

47-60 Determine whether there is an empty entry in the array of suspended threads and, if not, realloc the array with an extra entry.

65-78 The sentinel variable is initialized to 0, to detect when the target thread suspension occurs. The thread is sent a SIGUSR1 signal by calling pthread_kill, and thd_suspend loops, calling sched_yield to avoid monopolizing a processor, until the target thread responds by setting sentinel. Finally, the suspended thread's identifier is stored in the array.

¦ susp.c part 3 thd_suspend

1 /*

2 * Suspend a thread by sending it a signal (SIGUSR1), which will

3 * block the thread until another signal (SIGUSR2) arrives.

4 *

5 * Multiple calls to thd_suspend for a single thread have no

6 * additional effect on the thread — a single thd_continue

7 * call will cause it to resume execution.

8 */

9 int

10 thd_suspend (pthread_t target_thread)

11 {

12 int status;

13 int i = 0;

14

15 /*

16 * The first call to thd_suspend will initialize the

17 * package.

18 */

19 status = pthread_once (&once, suspend_init_routine);

20 if (status != 0)

21  return status;

22

23 /*

24 * Serialize access to suspend, makes life easier.

25 */

26 status = pthread_mutex_lock (&mut);

27 if (status != 0)

28  return status;

29

30 /*

31 * Threads that are suspended are added to the target_array;

32 * a request to suspend a thread already listed in the array

33 * is ignored. Sending a second SIGUSR1 would cause the

34 * thread to resuspend itself as soon as it is resumed.

35 */

36 while (i < bottom)

37  if (array[i++] == target_thread) {

38  status = pthread_mutex_unlock (&mut);

39  return status;

40 }

41

42 /*

43 * Ok, we really need to suspend this thread. So, let's find

44 * the location in the array that we'll use. If we run off

45 * the end, realloc the array for more space.

46 */

47 i = 0;

48 while (array[i] != 0)

49  i++;

50

51 if (i == bottom) {

52  array = (pthread_t*) realloc (

53  array, (++bottom * sizeof (pthread_t)));

54  if (array == NULL) {

55  pthread_mutex_unlock (&mut);

56  return errno;

57  }

58

59  array[bottom] = null_pthread; /* Clear new entry */

60 }

61

62 /*

63 * Clear the sentinel and signal the thread to suspend.

64 */

65 sentinel = 0;

66 status = pthread_kill (target_thread, SIGUSR1);

67 if (status != 0) {

68  pthread_mutex_unlock (&mut);

69  return status;

70 }

71

72 /*

73 * Wait for the sentinel to change.

74 */

75 while (sentinel == 0)

76  sched_yield ();

77

78 array[i] = target_thread;

79

80  status = pthread_mutex_unlock (&mut);

81  return status;

82 }

23-26 The thd_continue function first checks whether the suspend/resume package has been initialized (inited is not 0). If it has not been initialized, then no threads are suspended, and thd_continue returns with success.

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

0

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

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