[PD-cvs] pd/src s_inter.c,1.5.4.10,1.5.4.11

Tim Blechmann timblech at users.sourceforge.net
Thu Jun 16 14:47:53 CEST 2005


Update of /cvsroot/pure-data/pd/src
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17121

Modified Files:
      Tag: devel_0_38
	s_inter.c 
Log Message:
watchdog thread instead of process ... should be more efficient


Index: s_inter.c
===================================================================
RCS file: /cvsroot/pure-data/pd/src/s_inter.c,v
retrieving revision 1.5.4.10
retrieving revision 1.5.4.11
diff -C2 -d -r1.5.4.10 -r1.5.4.11
*** s_inter.c	14 May 2005 17:05:27 -0000	1.5.4.10
--- s_inter.c	16 Jun 2005 12:47:50 -0000	1.5.4.11
***************
*** 6,9 ****
--- 6,11 ----
  that didn't really belong anywhere. */
  
+ #define WATCHDOGTHREAD
+ 
  #include "m_pd.h"
  #include "s_stuff.h"
***************
*** 192,202 ****
  	*/
  
! 	if (microsec < 1000)
! 				microsec = 1000;
  #ifndef MSW
! 	struct timespec rec, rem;
! 	rec.tv_sec = 0;
! 	rec.tv_nsec = 1000 * microsec;
! 	nanosleep(&rec, &rem);
  #else
  	Sleep(microsec/1000);
--- 194,205 ----
  	*/
  
! /* 	if (!sys_callbackscheduler && microsec < 1000) */
! /* 		microsec = 1000; */
  #ifndef MSW
! 	struct timeval timeout;
! 	timeout.tv_sec = 0;
! 	timeout.tv_usec = microsec;
! 	select(0,0,0,0,&timeout);
! 
  #else
  	Sleep(microsec/1000);
***************
*** 204,208 ****
  	
  	/* a solution for lower timeslices might be a busysleep but this might
! 	   block a low-prority thread and won't work for win9x
  
  #define _WIN32_WINNT 0x0400
--- 207,211 ----
  	
  	/* a solution for lower timeslices might be a busysleep but this might
! 	   block a low-priority thread and won't work for win9x
  
  #define _WIN32_WINNT 0x0400
***************
*** 215,219 ****
  		SwitchToThread();
  #else 
! 		sched_yield()
  #endif
  	}
--- 218,222 ----
  		SwitchToThread();
  #else 
! 		sched_yield();
  #endif
  	}
***************
*** 299,303 ****
      p1 = sched_get_priority_min(SCHED_FIFO);
      p2 = sched_get_priority_max(SCHED_FIFO);
! #ifdef USEAPI_JACK    
      p3 = (higher ? p1 + 7 : p1 + 5);
  #else
--- 302,306 ----
      p1 = sched_get_priority_min(SCHED_FIFO);
      p2 = sched_get_priority_max(SCHED_FIFO);
! #ifdef USEAPI_JACK
      p3 = (higher ? p1 + 7 : p1 + 5);
  #else
***************
*** 857,860 ****
--- 860,864 ----
  void glob_watchdog(t_pd *dummy)
  {
+ #ifndef WATCHDOGTHREAD
      if (write(sys_watchfd, "\n", 1) < 1)
      {
***************
*** 862,865 ****
--- 866,873 ----
          sys_bail(1);
      }
+ #else
+ 
+ #endif
+ 
  }
  #endif
***************
*** 871,874 ****
--- 879,884 ----
          24, 15, 28};
  
+ static int sys_start_watchdog_thread();
+ 
  int sys_startgui(const char *guidir)
  {
***************
*** 1141,1144 ****
--- 1151,1155 ----
      if (sys_hipriority)
      {
+ #ifndef WATCHDOGTHREAD
              /* To prevent lockup, we fork off a watchdog process with
              higher real-time priority than ours.  The GUI has to send
***************
*** 1193,1196 ****
--- 1204,1211 ----
                  this is done later when the socket is open. */
          }
+ #else
+ 		sys_start_watchdog_thread();
+ 		sys_set_priority(0);
+ #endif
      }
  
***************
*** 1241,1247 ****
--- 1256,1264 ----
              /* here is where we start the pinging. */
  #if defined(__linux__) || defined(IRIX)
+ #ifndef WATCHDOGTHREAD
           if (sys_hipriority)
               sys_gui("pdtk_watchdog\n");
  #endif
+ #endif
           sys_get_audio_apis(buf);
           sys_vgui("pdtk_pd_startup {%s} %s {%s}\n", pd_version, buf, 
***************
*** 1288,1289 ****
--- 1305,1385 ----
  }
  
+ #include "pthread.h"
+ static pthread_t watchdog_id;
+ static pthread_t main_pd_thread;
+ static pthread_mutex_t watchdog_mutex = PTHREAD_MUTEX_INITIALIZER;
+ static pthread_cond_t watchdog_cond = PTHREAD_COND_INITIALIZER;
+ 
+ static void * watchdog_thread(void*);
+ 
+ /* start a high priority watchdog thread */
+ static int sys_start_watchdog_thread()
+ {
+ 	pthread_attr_t w_attr;
+ 	int status;
+ 	
+ 	/* get parent thread ID */
+ 	main_pd_thread = pthread_self();
+ 	
+ 	/* set up attributes */
+ 	pthread_attr_init(&w_attr);
+ 	
+ 	pthread_attr_setschedpolicy(&w_attr, SCHED_FIFO); /* use rt scheduling */
+ 	
+ 	status = pthread_create(&watchdog_id, &w_attr, (void*) watchdog_thread, NULL);
+ }
+ 
+ 
+ 
+ #ifdef MSW
+ int gettimeofday (struct timeval *tv, void* tz);
+ #endif
+ 
+ 
+ static t_int* watchdog_callback(t_int* dummy)
+ {
+ 	/* signal the condition */
+ 	pthread_cond_signal(&watchdog_cond);
+ 	return 0;
+ }
+ 
+ /* this watchdog thread registers an idle callback once a minute 
+    if the idle callback isn't excecuted within one minute, we're probably
+    blocking the system.
+    kill the whole process!
+ */
+ 
+ static void * watchdog_thread(void* dummy)
+ {
+ 	sys_set_priority(1);
+ 	post("watchdog thread started");
+ 
+ 	while (1)
+ 	{
+ 		/* - register idle callback
+ 		   - wait for condition variable
+ 		   - in case of timeout kill the parent thread 
+ 		   - sleep
+ 		*/
+ 		struct timespec timeout;
+ 		struct timeval now;
+ 		
+ 		int status;
+ 		
+ 		gettimeofday(&now,0);
+ 		timeout.tv_sec = now.tv_sec + 60; /* timeout: 60 seconds */
+ 		timeout.tv_nsec = now.tv_usec * 1000;
+ 
+ 		sys_callback((void*)watchdog_callback, 0, 0);
+ 		status = pthread_cond_timedwait(&watchdog_cond, &watchdog_mutex, &timeout);
+ 
+ 		if (status)
+ 		{
+ 			/* kill parent thread */
+ 			kill(0,9);
+ 		}
+ 		
+ 		sys_microsleep(6e7); /* and sleep for another 60 seconds */
+ 	}
+ }
+ 





More information about the Pd-cvs mailing list