[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