@@ -122,8 +122,7 @@ pthread_mutex_t susp_mut = PTHREAD_MUTEX_INITIALIZER;
122122volatile int susp_sentinel = 0 ;
123123pthread_once_t susp_once = PTHREAD_ONCE_INIT ;
124124pthread_t susp_null_pthread = {0 };
125- pthread_t susp_array [MAXTHREAD ];
126- int susp_bottom = MAXTHREAD ;
125+ int susp_count [MAXTHREAD ];
127126int susp_inited = 0 ;
128127
129128/*
@@ -134,14 +133,26 @@ void
134133suspend_signal_handler (int sig )
135134{
136135 sigset_t signal_set ;
136+ susp_count [thr_self ()] += 1 ;
137137
138138 /*
139- * Block all signals except SIGUSR2 while suspended.
139+ * Skip if already suspended
140+ */
141+ if (susp_count [thr_self ()]> 1 ) {
142+ susp_sentinel = 1 ;
143+ return ;
144+ }
145+
146+ /*
147+ * Block all signals except SIGUSR1 and SIGUSR2 while suspended.
140148 */
141149 sigfillset (& signal_set );
150+ sigdelset (& signal_set , SIGUSR1 );
142151 sigdelset (& signal_set , SIGUSR2 );
143152 susp_sentinel = 1 ;
144- sigsuspend (& signal_set );
153+ while (susp_count [thr_self ()]> 0 ) {
154+ sigsuspend (& signal_set );
155+ }
145156
146157 /*
147158 * Once I'm here, I've been resumed, and the resume signal
@@ -158,6 +169,7 @@ suspend_signal_handler (int sig)
158169void
159170resume_signal_handler (int sig )
160171{
172+ susp_count [thr_self ()] -= 1 ;
161173 return ;
162174}
163175
@@ -168,15 +180,15 @@ resume_signal_handler (int sig)
168180void
169181suspend_init_routine (void )
170182{
171- int status ;
183+ int i , status ;
172184 struct sigaction sigusr1 , sigusr2 ;
173185
174186 /*
175- * Allocate the suspended threads array. This array is used
176- * to guarentee idempotency
187+ * Initialize suspension counter
177188 */
178- //susp_bottom = 10;
179- // susp_array = (pthread_t*) calloc (susp_bottom, sizeof (pthread_t));
189+ for (i = 0 ; i < MAXTHREAD ; i ++ ) {
190+ susp_count [i ] = 0 ;
191+ }
180192
181193 /*
182194 * Install the signal handlers for suspend/resume.
@@ -210,11 +222,10 @@ suspend_init_routine (void)
210222 * call will cause it to resume execution.
211223 */
212224int
213- //thd_suspend (pthread_t target_thread)
225+ //thr_suspend (pthread_t target_thread)
214226pthread_suspend (pthread_t target_thread )
215227{
216228 int status ;
217- int i = 0 ;
218229
219230 /*
220231 * The first call to thd_suspend will initialize the
@@ -231,38 +242,6 @@ pthread_suspend (pthread_t target_thread)
231242 if (status != 0 )
232243 return status ;
233244
234- /*
235- * Threads that are suspended are added to the target_array;
236- * a request to suspend a thread already listed in the array
237- * is ignored. Sending a second SIGUSR1 would cause the
238- * thread to re-suspend itself as soon as it is resumed.
239- */
240- while (i < susp_bottom )
241- if (susp_array [i ++ ] == target_thread ) {
242- status = pthread_mutex_unlock (& susp_mut );
243- return status ;
244- }
245-
246- /*
247- * Ok, we really need to suspend this thread. So, lets find
248- * the location in the array that we'll use. If we run off
249- * the end, realloc the array for more space.
250- */
251- i = 0 ;
252- while (susp_array [i ] != 0 )
253- i ++ ;
254-
255- if (i == susp_bottom ) {
256- // susp_array = (pthread_t*) realloc (
257- // susp_array, (++susp_bottom * sizeof (pthread_t)));
258- // if (susp_array == NULL) {
259- pthread_mutex_unlock (& susp_mut );
260- return errno ;
261- // }
262-
263- // susp_array[susp_bottom] = susp_null_pthread; /* Clear new entry */
264- }
265-
266245 /*
267246 * Clear the sentinel and signal the thread to suspend.
268247 */
@@ -279,23 +258,22 @@ pthread_suspend (pthread_t target_thread)
279258 while (susp_sentinel == 0 )
280259 sched_yield ();
281260
282- susp_array [i ] = target_thread ;
283-
284261 status = pthread_mutex_unlock (& susp_mut );
285262 return status ;
286263}
287264
288265/*
289266 * Resume a suspended thread by sending it SIGUSR2 to break
290267 * it out of the sigsuspend() in which it's waiting. If the
291- * target thread isn't suspended, return with success.
268+ * thread has received other suspension requests while waiting,
269+ * the thread will be re-suspended immediately after resuming.
270+ * If the target thread isn't suspended, return with success.
292271 */
293272int
294- //thd_continue (pthread_t target_thread)
295- pthread_continue (pthread_t target_thread )
273+ pthread_unsuspend (pthread_t target_thread )
296274{
297275 int status ;
298- int i = 0 ;
276+
299277 /*
300278 * Serialize access to suspend, makes life easier
301279 */
@@ -312,19 +290,6 @@ pthread_continue (pthread_t target_thread)
312290 return status ;
313291 }
314292
315- /*
316- * Make sure the thread is in the suspend array. If not, it
317- * hasn't been suspended (or it has already been resumed) and
318- * we can just carry on.
319- */
320- while (susp_array [i ] != target_thread && i < susp_bottom )
321- i ++ ;
322-
323- if (i >= susp_bottom ) {
324- pthread_mutex_unlock (& susp_mut );
325- return 0 ;
326- }
327-
328293 /*
329294 * Signal the thread to continue, and remove the thread from
330295 * the suspended array.
@@ -335,10 +300,34 @@ pthread_continue (pthread_t target_thread)
335300 return status ;
336301 }
337302
338- susp_array [i ] = 0 ; /* Clear array element */
339303 status = pthread_mutex_unlock (& susp_mut );
340304 return status ;
341305}
306+
307+ /*
308+ * Ensures that a suspended thread is resumed, even if
309+ * multiple suspension requests have been received.
310+ */
311+ int
312+ //thr_continue (pthread_t target_thread)
313+ pthread_continue (pthread_t target_thread )
314+ {
315+ int i ;
316+ for (i = 0 ; i < MAXTHREAD && !pthread_equal (thread_table [i ].tid ,target_thread ); i ++ );
317+ if (i == MAXTHREAD ) return (-1 );
318+
319+ susp_count [i ] = 1 ;
320+ return pthread_unsuspend (target_thread );
321+ }
322+
323+ int thr_unsuspend ( int tid ) {
324+ return pthread_unsuspend ( thread_table [tid ].tid );
325+ }
326+ #else
327+ int thr_unsuspend ( int tid ) {
328+ // not supported, always continue
329+ return pthread_continue ( thread_table [tid ].tid );
330+ }
342331#endif
343332int thr_suspend ( int tid ) {
344333 return pthread_suspend ( thread_table [tid ].tid );
0 commit comments