Browse code

- darwin sigwait() bug workaround: on darwin sigwait is buggy: it will cause extreme slow down on signal delivery for the signals it doesn't wait on (I've measured a 36s delay on a 1.5Ghz powerbook). The workaround is: sigwait() on all the signals we are interested in ser and manually call the master signal handler (sig_usr(sig_no)) if the signal!= slow timer signal.

Andrei Pelinescu-Onciul authored on 26/05/2007 11:12:29
Showing 2 changed files
... ...
@@ -644,7 +644,7 @@ void handle_sigs()
644 644
     - modified by andrei: moved most of the stuff to handle_sigs,
645 645
        made it safer for the "fork" case
646 646
 */
647
-static void sig_usr(int signo)
647
+void sig_usr(int signo)
648 648
 {
649 649
 
650 650
 
... ...
@@ -29,8 +29,10 @@
29 29
  *  2003-03-19  replaced all the mallocs/frees w/ pkg_malloc/pkg_free (andrei)
30 30
  *  2003-03-29  cleaning pkg_mallocs introduced (jiri)
31 31
  *  2005-07-27  complete re-design/re-implementation (andrei)
32
- *  2005-12-12  workarround & bug reporting for timer_del(self) called from
32
+ *  2005-12-12  workaround & bug reporting for timer_del(self) called from
33 33
  *              a timer handle; added timer_allow_del()  (andrei)
34
+ *  2007-05-26  workaround for darwin sigwait() bug, see slow_timer_main() or
35
+ *              grep __OS_darwin for more info (andrei)
34 36
  */
35 37
 
36 38
 
... ...
@@ -340,6 +342,17 @@ again:
340 340
 				strerror(errno), errno);
341 341
 		goto error;
342 342
 	}
343
+#ifdef __OS_darwin
344
+	/* workaround for darwin sigwait bug, see slow_timer_main() for more
345
+	   info (or grep __OS_darwin) */
346
+	/* keep in sync wih main.c: sig_usr() - signals we are interested in */
347
+	sigaddset(&slow_timer_sset, SIGINT);
348
+	sigaddset(&slow_timer_sset, SIGTERM);
349
+	sigaddset(&slow_timer_sset, SIGUSR1);
350
+	sigaddset(&slow_timer_sset, SIGHUP);
351
+	sigaddset(&slow_timer_sset, SIGCHLD);
352
+	sigaddset(&slow_timer_sset, SIGALRM);
353
+#endif
343 354
 	return 0;
344 355
 error:
345 356
 	return -1;
... ...
@@ -989,17 +1002,24 @@ ticks_t get_ticks()
989 989
  *   -it  increments *s_idx (at the end it will be == *t_idx)
990 990
  *   -all list operations are protected by the "slow" timer lock
991 991
  */
992
+#ifdef __OS_darwin
993
+extern void sig_usr(int signo);
994
+#endif
995
+
992 996
 void slow_timer_main()
993 997
 {
994 998
 	int n;
995 999
 	ticks_t ret;
996 1000
 	struct timer_ln* tl;
997 1001
 	unsigned short i;
1002
+#ifdef USE_SIGWAIT
1003
+	int sig;
1004
+#endif
998 1005
 	
999 1006
 	in_slow_timer=1; /* mark this process as the slow timer */
1000 1007
 	while(1){
1001 1008
 #ifdef USE_SIGWAIT
1002
-		n=sigwait(&slow_timer_sset, 0);
1009
+		n=sigwait(&slow_timer_sset, &sig);
1003 1010
 #else
1004 1011
 		n=sigwaitinfo(&slow_timer_sset, 0);
1005 1012
 #endif
... ...
@@ -1010,6 +1030,20 @@ void slow_timer_main()
1010 1010
 			sleep(1);
1011 1011
 			/* try to continue */
1012 1012
 		}
1013
+#ifdef USE_SIGWAIT
1014
+	if (sig!=SLOW_TIMER_SIG){
1015
+#ifdef __OS_darwin
1016
+		/* on darwin sigwait is buggy: it will cause extreme slow down
1017
+		   on signal delivery for the signals it doesn't wait on
1018
+		   (on darwin 8.8.0, g4 1.5Ghz I've measured a 36s delay!).
1019
+		  To work arround this bug, we sigwait() on all the signals we
1020
+		  are interested in ser and manually call the master signal handler 
1021
+		  if the signal!= slow timer signal -- andrei */
1022
+		sig_usr(sig);
1023
+#endif
1024
+		continue;
1025
+	}
1026
+#endif
1013 1027
 		LOCK_SLOW_TIMER_LIST();
1014 1028
 		while(*s_idx!=*t_idx){
1015 1029
 			i= *s_idx%SLOW_LISTS_NO;