libc: improve alignment of QLp structure on amd64, cosmetics

the QLp structure used to occupy 24 bytes on amd64.
with some rearranging the fields we can get it to 16 bytes,
saving 8K in the data section for the 1024 preallocated
structs in the ql arena.

the rest of the changes are of cosmetic nature:

- getqlp() zeros the next pointer, so there is no need to set
  it when queueing the entry.

- always explicitely compare pointers to nil.

- delete unused code from ape's qlock.c
This commit is contained in:
cinap_lenrek 2017-10-28 18:53:27 +02:00
parent 4fc4b0dda7
commit 3794b1c14f
4 changed files with 9 additions and 267 deletions

View file

@ -13,8 +13,8 @@ typedef struct QLp QLp;
struct QLp
{
int inuse;
int state;
QLp *next;
char state;
};
typedef

View file

@ -435,8 +435,8 @@ typedef struct QLp QLp;
struct QLp
{
int inuse;
int state;
QLp *next;
char state;
};
typedef

View file

@ -22,9 +22,6 @@ static struct {
enum
{
Queuing,
QueuingR,
QueuingW,
Sleeping,
};
/* find a free shared memory location to queue ourselves in */
@ -41,10 +38,10 @@ getqlp(void)
abort();
if(_tas(&(p->inuse)) == 0){
ql.p = p;
p->next = nil;
break;
}
}
p->next = nil;
return p;
}
@ -60,7 +57,6 @@ qlock(QLock *q)
return;
}
/* chain into waiting list */
mp = getqlp();
p = q->tail;
@ -112,254 +108,3 @@ canqlock(QLock *q)
unlock(&q->lock);
return 0;
}
#if 0
void
rlock(RWLock *q)
{
QLp *p, *mp;
lock(&q->lock);
if(q->writer == 0 && q->head == nil){
/* no writer, go for it */
q->readers++;
unlock(&q->lock);
return;
}
mp = getqlp();
p = q->tail;
if(p == 0)
q->head = mp;
else
p->next = mp;
q->tail = mp;
mp->next = nil;
mp->state = QueuingR;
unlock(&q->lock);
/* wait in kernel */
while((*_rendezvousp)(mp, (void*)1) == (void*)~0)
;
mp->inuse = 0;
}
int
canrlock(RWLock *q)
{
lock(&q->lock);
if (q->writer == 0 && q->head == nil) {
/* no writer; go for it */
q->readers++;
unlock(&q->lock);
return 1;
}
unlock(&q->lock);
return 0;
}
void
runlock(RWLock *q)
{
QLp *p;
lock(&q->lock);
if(q->readers <= 0)
abort();
p = q->head;
if(--(q->readers) > 0 || p == nil){
unlock(&q->lock);
return;
}
/* start waiting writer */
if(p->state != QueuingW)
abort();
q->head = p->next;
if(q->head == 0)
q->tail = 0;
q->writer = 1;
unlock(&q->lock);
/* wakeup waiter */
while((*_rendezvousp)(p, (void*)0) == (void*)~0)
;
}
void
wlock(RWLock *q)
{
QLp *p, *mp;
lock(&q->lock);
if(q->readers == 0 && q->writer == 0){
/* noone waiting, go for it */
q->writer = 1;
unlock(&q->lock);
return;
}
/* wait */
p = q->tail;
mp = getqlp();
if(p == nil)
q->head = mp;
else
p->next = mp;
q->tail = mp;
mp->next = nil;
mp->state = QueuingW;
unlock(&q->lock);
/* wait in kernel */
while((*_rendezvousp)(mp, (void*)1) == (void*)~0)
;
mp->inuse = 0;
}
int
canwlock(RWLock *q)
{
lock(&q->lock);
if (q->readers == 0 && q->writer == 0) {
/* no one waiting; go for it */
q->writer = 1;
unlock(&q->lock);
return 1;
}
unlock(&q->lock);
return 0;
}
void
wunlock(RWLock *q)
{
QLp *p;
lock(&q->lock);
if(q->writer == 0)
abort();
p = q->head;
if(p == nil){
q->writer = 0;
unlock(&q->lock);
return;
}
if(p->state == QueuingW){
/* start waiting writer */
q->head = p->next;
if(q->head == nil)
q->tail = nil;
unlock(&q->lock);
while((*_rendezvousp)(p, (void*)0) == (void*)~0)
;
return;
}
if(p->state != QueuingR)
abort();
/* wake waiting readers */
while(q->head != nil && q->head->state == QueuingR){
p = q->head;
q->head = p->next;
q->readers++;
while((*_rendezvousp)(p, (void*)0) == (void*)~0)
;
}
if(q->head == nil)
q->tail = nil;
q->writer = 0;
unlock(&q->lock);
}
void
rsleep(Rendez *r)
{
QLp *t, *me;
if(!r->l)
abort();
lock(&r->l->lock);
/* we should hold the qlock */
if(!r->l->locked)
abort();
/* add ourselves to the wait list */
me = getqlp();
me->state = Sleeping;
if(r->head == nil)
r->head = me;
else
r->tail->next = me;
me->next = nil;
r->tail = me;
/* pass the qlock to the next guy */
t = r->l->head;
if(t){
r->l->head = t->next;
if(r->l->head == nil)
r->l->tail = nil;
unlock(&r->l->lock);
while((*_rendezvousp)(t, (void*)0x12345) == (void*)~0)
;
}else{
r->l->locked = 0;
unlock(&r->l->lock);
}
/* wait for a wakeup */
while((*_rendezvousp)(me, (void*)1) == (void*)~0)
;
me->inuse = 0;
}
int
rwakeup(Rendez *r)
{
QLp *t;
/*
* take off wait and put on front of queue
* put on front so guys that have been waiting will not get starved
*/
if(!r->l)
abort();
lock(&r->l->lock);
if(!r->l->locked)
abort();
t = r->head;
if(t == nil){
unlock(&r->l->lock);
return 0;
}
r->head = t->next;
if(r->head == nil)
r->tail = nil;
t->next = r->l->head;
r->l->head = t;
if(r->l->tail == nil)
r->l->tail = t;
t->state = Queuing;
unlock(&r->l->lock);
return 1;
}
int
rwakeupall(Rendez *r)
{
int i;
for(i=0; rwakeup(r); i++)
;
return i;
}
#endif

View file

@ -39,10 +39,10 @@ getqlp(void)
abort();
if(_tas(&(p->inuse)) == 0){
ql.p = p;
p->next = nil;
break;
}
}
p->next = nil;
return p;
}
@ -128,12 +128,11 @@ rlock(RWLock *q)
mp = getqlp();
p = q->tail;
if(p == 0)
if(p == nil)
q->head = mp;
else
p->next = mp;
q->tail = mp;
mp->next = nil;
mp->state = QueuingR;
unlock(&q->lock);
@ -199,14 +198,13 @@ wlock(RWLock *q)
}
/* wait */
p = q->tail;
mp = getqlp();
p = q->tail;
if(p == nil)
q->head = mp;
else
p->next = mp;
q->tail = mp;
mp->next = nil;
mp->state = QueuingW;
unlock(&q->lock);
@ -286,7 +284,7 @@ rsleep(Rendez *r)
{
QLp *t, *me;
if(!r->l)
if(r->l == nil)
abort();
lock(&r->l->lock);
/* we should hold the qlock */
@ -300,12 +298,11 @@ rsleep(Rendez *r)
r->head = me;
else
r->tail->next = me;
me->next = nil;
r->tail = me;
/* pass the qlock to the next guy */
t = r->l->head;
if(t){
if(t != nil){
r->l->head = t->next;
if(r->l->head == nil)
r->l->tail = nil;
@ -333,7 +330,7 @@ rwakeup(Rendez *r)
* put on front so guys that have been waiting will not get starved
*/
if(!r->l)
if(r->l == nil)
abort();
lock(&r->l->lock);
if(!r->l->locked)