Subj : Re: Hazard Pointers w/o memory barrier. To : comp.programming.threads From : Chris Thomasson Date : Tue Apr 19 2005 11:31 am > On Solaris and possibly Aix, you can use /proc to get context switching > counts > for threads to use as quiesce points. For other unices and Linux, you > will need > to periodically signal each thread to execute a signal handler that > increments > a signal count to use as quiesce points. For windows, there's no > asynchronous > signal facility or /proc, but there's a hack that will work. I won't > disclose it since > I don't support windows and I want to see how long it takes someone else > to figure it out. You can "probably" use GetThreadTimes and check the kernel time for per-thread changes. Here is the scheme I have in mind: typedef struct per_thread_ { struct per_thread_ *next; HANDLE thread; LONG old_q; // = 0 LONG new_q; // = 0 FILETIME old_ktime; FILETIME new_ktime; } per_thread_t; static per_thread_t *g_rcu_threads = 0; static LONG g_rcu_period = 0; static HANDLE g_rcu_poll; /* auto-reset */ static CRITICAL_SECTION g_rcu_mutex; VOID ScanForQuiescentState() { per_thread_t *t = g_rcu_threads; FILETIME c, x, u; while ( t ) { if ( t->old_q == t->new_q ) { GetThreadTimes ( t->thread, &c, &x, &t->new_ktime, &u ); if ( t->new_ktime.dwLowDateTime != t->old_ktime.dwLowDateTime || t->new_ktime.dwHighDateTime != t->old_ktime.dwHighDateTime ) { ++t->new_q; } } t = t->next; } } BOOL ScanForQuiescentPeriod() { BOOL period = TRUE; per_thread_t *t = g_rcu_threads; while ( t ) { if ( t->old_q == t->new_q ) { period = FALSE; } t = t->next; } } VOID HandleQuiescentPeriod() { per_thread_t *t = g_rcu_threads; while ( t ) { assert( t->old_q != t->new_q ); // xchg (t)'s callback lists, and fire them // reset t->old_ktime = t->new_ktime; t->old_q = t->new_q; t = t->next; } ++g_rcu_period; } The polling thread would do something like this: for ( ;; ) { WaitForSingleObject( g_rcu_poll, 500 ); EnterCriticalSection( &g_rcu_mutex ); ScanForQuiescentState(); if ( ScanForQuiescentPeriod() ) { // All threads have been through quiescent state HandleQuiescentPeriod(); } LeaveCriticalSection( &g_rcu_mutex ); } What do ya think Joe? ;) .