mirror of
https://github.com/0intro/conterm
synced 2024-11-22 05:41:28 +03:00
95 lines
1.1 KiB
C
95 lines
1.1 KiB
C
#include "u.h"
|
|
#include "lib.h"
|
|
#include "dat.h"
|
|
#include "fns.h"
|
|
|
|
static void
|
|
queue(Proc **first, Proc **last)
|
|
{
|
|
Proc *t;
|
|
|
|
t = *last;
|
|
if(t == 0)
|
|
*first = up;
|
|
else
|
|
t->qnext = up;
|
|
*last = up;
|
|
up->qnext = 0;
|
|
}
|
|
|
|
static Proc*
|
|
dequeue(Proc **first, Proc **last)
|
|
{
|
|
Proc *t;
|
|
|
|
t = *first;
|
|
if(t == 0)
|
|
return 0;
|
|
*first = t->qnext;
|
|
if(*first == 0)
|
|
*last = 0;
|
|
return t;
|
|
}
|
|
|
|
void
|
|
qlock(QLock *q)
|
|
{
|
|
lock(&q->lk);
|
|
|
|
if(q->hold == 0) {
|
|
q->hold = up;
|
|
unlock(&q->lk);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* Can't assert this because of RWLock
|
|
assert(q->hold != up);
|
|
*/
|
|
|
|
queue((Proc**)&q->first, (Proc**)&q->last);
|
|
unlock(&q->lk);
|
|
procsleep();
|
|
}
|
|
|
|
int
|
|
canqlock(QLock *q)
|
|
{
|
|
lock(&q->lk);
|
|
if(q->hold == 0) {
|
|
q->hold = up;
|
|
unlock(&q->lk);
|
|
return 1;
|
|
}
|
|
unlock(&q->lk);
|
|
return 0;
|
|
}
|
|
|
|
void
|
|
qunlock(QLock *q)
|
|
{
|
|
Proc *p;
|
|
|
|
lock(&q->lk);
|
|
/*
|
|
* Can't assert this because of RWlock
|
|
assert(q->hold == CT);
|
|
*/
|
|
p = dequeue((Proc**)&q->first, (Proc**)&q->last);
|
|
if(p) {
|
|
q->hold = p;
|
|
unlock(&q->lk);
|
|
procwakeup(p);
|
|
} else {
|
|
q->hold = 0;
|
|
unlock(&q->lk);
|
|
}
|
|
}
|
|
|
|
int
|
|
holdqlock(QLock *q)
|
|
{
|
|
return q->hold == up;
|
|
}
|
|
|