add _procwakeupandunlock
to help ease locking contention on Linux 2.4.
This commit is contained in:
parent
815552b9ed
commit
a0a331aad9
5 changed files with 44 additions and 12 deletions
|
|
@ -32,7 +32,7 @@ _threadlock(Lock *l, int block, ulong pc)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
static int first=1;
|
static int first=1;
|
||||||
if(first) {first=0; fmtinstall('T', timefmt);}
|
if(first) {first=0; fmtinstall('\001', timefmt);}
|
||||||
|
|
||||||
USED(pc);
|
USED(pc);
|
||||||
|
|
||||||
|
|
@ -48,43 +48,43 @@ if(first) {first=0; fmtinstall('T', timefmt);}
|
||||||
return 1;
|
return 1;
|
||||||
sched_yield();
|
sched_yield();
|
||||||
}
|
}
|
||||||
/* now nice and slow */
|
/* now increasingly slow */
|
||||||
for(i=0; i<10; i++){
|
for(i=0; i<10; i++){
|
||||||
if(!_tas(&l->held))
|
if(!_tas(&l->held))
|
||||||
return 1;
|
return 1;
|
||||||
usleep(1);
|
usleep(1);
|
||||||
}
|
}
|
||||||
fprint(2, "%T lock loop %p from %lux\n", l, pc);
|
fprint(2, "%\001 %s: lock loop1 %p from %lux\n", argv0, l, pc);
|
||||||
for(i=0; i<10; i++){
|
for(i=0; i<10; i++){
|
||||||
if(!_tas(&l->held))
|
if(!_tas(&l->held))
|
||||||
return 1;
|
return 1;
|
||||||
usleep(10);
|
usleep(10);
|
||||||
}
|
}
|
||||||
fprint(2, "%T lock loop %p from %lux\n", l, pc);
|
fprint(2, "%\001 %s: lock loop2 %p from %lux\n", argv0, l, pc);
|
||||||
for(i=0; i<10; i++){
|
for(i=0; i<10; i++){
|
||||||
if(!_tas(&l->held))
|
if(!_tas(&l->held))
|
||||||
return 1;
|
return 1;
|
||||||
usleep(100);
|
usleep(100);
|
||||||
}
|
}
|
||||||
fprint(2, "%T lock loop %p from %lux\n", l, pc);
|
fprint(2, "%\001 %s: lock loop3 %p from %lux\n", argv0, l, pc);
|
||||||
for(i=0; i<10; i++){
|
for(i=0; i<10; i++){
|
||||||
if(!_tas(&l->held))
|
if(!_tas(&l->held))
|
||||||
return 1;
|
return 1;
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
}
|
}
|
||||||
fprint(2, "%T lock loop %p from %lux\n", l, pc);
|
fprint(2, "%\001 %s: lock loop4 %p from %lux\n", argv0, l, pc);
|
||||||
for(i=0; i<10; i++){
|
for(i=0; i<10; i++){
|
||||||
if(!_tas(&l->held))
|
if(!_tas(&l->held))
|
||||||
return 1;
|
return 1;
|
||||||
usleep(10*1000);
|
usleep(10*1000);
|
||||||
}
|
}
|
||||||
fprint(2, "%T lock loop %p from %lux\n", l, pc);
|
fprint(2, "%\001 %s: lock loop5 %p from %lux\n", argv0, l, pc);
|
||||||
for(i=0; i<1000; i++){
|
for(i=0; i<1000; i++){
|
||||||
if(!_tas(&l->held))
|
if(!_tas(&l->held))
|
||||||
return 1;
|
return 1;
|
||||||
usleep(100*1000);
|
usleep(100*1000);
|
||||||
}
|
}
|
||||||
fprint(2, "%T lock loop %p from %lux\n", l, pc);
|
fprint(2, "%\001 %s: lock loop6 %p from %lux\n", argv0, l, pc);
|
||||||
/* take your time */
|
/* take your time */
|
||||||
while(_tas(&l->held))
|
while(_tas(&l->held))
|
||||||
usleep(1000*1000);
|
usleep(1000*1000);
|
||||||
|
|
@ -150,13 +150,20 @@ again:
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_procwakeup(_Procrendez *r)
|
_procwakeupandunlock(_Procrendez *r)
|
||||||
{
|
{
|
||||||
|
int pid;
|
||||||
|
|
||||||
|
pid = 0;
|
||||||
if(r->asleep){
|
if(r->asleep){
|
||||||
r->asleep = 0;
|
r->asleep = 0;
|
||||||
assert(r->pid >= 1);
|
assert(r->pid >= 1);
|
||||||
kill(r->pid, SIGUSR1);
|
pid = r->pid;
|
||||||
}
|
}
|
||||||
|
assert(r->l);
|
||||||
|
unlock(r->l);
|
||||||
|
if(pid)
|
||||||
|
kill(pid, SIGUSR1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/resource.h>
|
||||||
#include "threadimpl.h"
|
#include "threadimpl.h"
|
||||||
|
|
||||||
#undef waitpid
|
#undef waitpid
|
||||||
|
|
@ -11,6 +14,7 @@ static void
|
||||||
child(void)
|
child(void)
|
||||||
{
|
{
|
||||||
int status, pid;
|
int status, pid;
|
||||||
|
struct rlimit rl;
|
||||||
|
|
||||||
notedisable("sys: child");
|
notedisable("sys: child");
|
||||||
pid = waitpid(sigpid, &status, 0);
|
pid = waitpid(sigpid, &status, 0);
|
||||||
|
|
@ -21,6 +25,14 @@ child(void)
|
||||||
if(WIFEXITED(status))
|
if(WIFEXITED(status))
|
||||||
_exit(WEXITSTATUS(status));
|
_exit(WEXITSTATUS(status));
|
||||||
if(WIFSIGNALED(status)){
|
if(WIFSIGNALED(status)){
|
||||||
|
/*
|
||||||
|
* Make sure we don't scribble over the nice
|
||||||
|
* core file that our child just wrote out.
|
||||||
|
*/
|
||||||
|
rl.rlim_cur = 0;
|
||||||
|
rl.rlim_max = 0;
|
||||||
|
setrlimit(RLIMIT_CORE, &rl);
|
||||||
|
|
||||||
signal(WTERMSIG(status), SIG_DFL);
|
signal(WTERMSIG(status), SIG_DFL);
|
||||||
raise(WTERMSIG(status));
|
raise(WTERMSIG(status));
|
||||||
_exit(98); /* not reached */
|
_exit(98); /* not reached */
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,16 @@ _procwakeup(_Procrendez *r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_procwakeupandunlock(_Procrendez *r)
|
||||||
|
{
|
||||||
|
if(r->asleep){
|
||||||
|
r->asleep = 0;
|
||||||
|
pthread_cond_signal(&r->cond);
|
||||||
|
}
|
||||||
|
unlock(&r->l);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
startprocfn(void *v)
|
startprocfn(void *v)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -166,10 +166,12 @@ _threadready(_Thread *t)
|
||||||
|
|
||||||
p = t->proc;
|
p = t->proc;
|
||||||
lock(&p->lock);
|
lock(&p->lock);
|
||||||
|
p->runrend.l = &p->lock;
|
||||||
addthread(&p->runqueue, t);
|
addthread(&p->runqueue, t);
|
||||||
//print("%d wake for job %d->%d\n", time(0), getpid(), p->osprocid);
|
//print("%d wake for job %d->%d\n", time(0), getpid(), p->osprocid);
|
||||||
if(p != proc())
|
if(p != proc())
|
||||||
_procwakeup(&p->runrend);
|
_procwakeupandunlock(&p->runrend);
|
||||||
|
else
|
||||||
unlock(&p->lock);
|
unlock(&p->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,7 @@ struct _Procrendez
|
||||||
|
|
||||||
extern void _procsleep(_Procrendez*);
|
extern void _procsleep(_Procrendez*);
|
||||||
extern void _procwakeup(_Procrendez*);
|
extern void _procwakeup(_Procrendez*);
|
||||||
|
extern void _procwakeupandunlock(_Procrendez*);
|
||||||
|
|
||||||
struct Proc
|
struct Proc
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue