clock() is a system call which takes a small but not insignificant amount of cpu time. The reason for the div_ construction is that check_threads is called a *lot*. Even using up a few cycles in this function creates measurable slowdowns.
My suggestion would be to make the code look something like:
static int divisor; static int context_switches; static float cps=50.0; static float last_time=-1.0;
void check_threads() { static int counter=0; if(counter--) return;
counter=divisor; context_switches++; ... }
And then, in some code which is called more seldom:
float t=float_time(); if(last_time != -1.0) { float s=10.0; /* Average time */ float frac=1.0-1.0/s;
cps=cps * pow(frac,t - last_time) + context_switches/s; } context_switches=0; last_time=t;
if(cps < 20) divisor -= divisor / 5; if(cps > 100) divisor += divisor / 3;
This way, it will adapt automatically, not use much cpu, and you can fall back to gettimeofday() if you like, because the adaption function is not called as often.
As far as I'm concerned, it doesn't matter if time slices are uniform in length.
/ Fredrik (Naranek) Hubinette (Real Build Master)
Previous text:
2002-09-05 18:20: Subject: Frequent context switches
Looks like the fallback if gethrtime doesn't exist is a bit arbitrary:
static void check_threads(struct callback *cb, void *arg, void * arg2) { #ifdef HAVE_GETHRTIME static long long last_; if( gethrtime()-last_ < 50000000 ) /* 0.05s slice */ return; last_ = gethrtime(); #else static int div_; if(div_++ & 255) return; #endif
This only works if check_threads is called at approximately even time intervals, which probably isn't true at all.
I'd like to add a fallback to clock():
#elif defined(USE_CLOCK_FOR_SLICES) if (clock() - thread_start_clock < (clock_t) (CLOCKS_PER_SEC / 20)) return; #else
where thread_start_clock is set to clock() in SWAP_IN_THREADS (since clock() measures the thread local cpu time).
Thoughts? I know that clock() has bad precision, but I think it should be adequate down to the 1/20 sec resolution used here.
/ Martin Stjernholm, Roxen IS