commit - 8b9a1d4cfefb87cb89835880d528ce8d8b5eecdc
commit + 615e0f9fb2df0e782f6b32ea9f0f67254e1ddeaf
blob - 9424d37e8d0f7f777c61d0dfeb63d8ac7a701252
blob + 94c99a25d8f7e014ac4ff8fa49a07738cae4cf9d
--- include/thread.h
+++ include/thread.h
void threadsetstate(char*, ...);
char *threadgetname(void);
int threadyield(void);
+int threadidle(void);
void _threadready(_Thread*);
void _threadswitch(void);
void _threadsetsysproc(void);
blob - ca4d35af66a0a348ff5d94e8ed1600ebb920e7bb
blob + 8a5643b0ca18ea513d5e484c22d6d11164664360
--- src/libthread/thread.c
+++ src/libthread/thread.c
}
int
+threadidle(void)
+{
+ int n;
+ Proc *p;
+
+ p = proc();
+ n = p->nswitch;
+ lock(&p->lock);
+ p->runrend.l = &p->lock;
+ addthread(&p->idlequeue, p->thread);
+ unlock(&p->lock);
+ _threadswitch();
+ return p->nswitch - n;
+}
+
+int
threadyield(void)
{
int n;
while((t = p->runqueue.head) == nil){
if(p->nthread == 0)
goto Out;
+ if((t = p->idlequeue.head) != nil){
+ /*
+ * Run all the idling threads once.
+ */
+ while((t = p->idlequeue.head) != nil){
+ delthread(&p->idlequeue, t);
+ addthread(&p->runqueue, t);
+ }
+ continue;
+ }
p->runrend.l = &p->lock;
_threaddebug("scheduler sleep");
_procsleep(&p->runrend);
if(t->exiting){
delthreadinproc(p, t);
p->nthread--;
-//print("ntrhead %d\n", p->nthread);
+//print("nthread %d\n", p->nthread);
free(t);
}
}
argv0 = argv[0];
- _threadsetupdaemonize();
+ if(getenv("NOLIBTHREADDAEMONIZE") == nil)
+ _threadsetupdaemonize();
threadargc = argc;
threadargv = argv;
blob - 33644657f4396ec9101b7cb6c7025df4a18a7846
blob + d1f3e9383dc3091aeed3b2ba3c792a1b1ad45ee9
--- src/libthread/threadimpl.h
+++ src/libthread/threadimpl.h
int nswitch;
_Thread *thread;
_Threadlist runqueue;
+ _Threadlist idlequeue;
_Threadlist allthreads;
uint nthread;
uint sysproc;