#include "runtime.h"
#line 22 "sema.cgo"
typedef struct Sema Sema;
struct Sema
{
uint32 *addr;
G *g;
Sema *prev;
Sema *next;
} ;
#line 32 "sema.cgo"
static Sema *semfirst , *semlast;
static Lock semlock;
#line 35 "sema.cgo"
static void
semqueue ( uint32 *addr , Sema *s )
{
s->addr = addr;
s->g = nil;
#line 41 "sema.cgo"
lock ( &semlock ) ;
s->prev = semlast;
s->next = nil;
if ( semlast )
semlast->next = s;
else
semfirst = s;
semlast = s;
unlock ( &semlock ) ;
}
#line 52 "sema.cgo"
static void
semdequeue ( Sema *s )
{
lock ( &semlock ) ;
if ( s->next )
s->next->prev = s->prev;
else
semlast = s->prev;
if ( s->prev )
s->prev->next = s->next;
else
semfirst = s->next;
s->prev = nil;
s->next = nil;
unlock ( &semlock ) ;
}
#line 69 "sema.cgo"
static void
semwakeup ( uint32 *addr )
{
Sema *s;
#line 74 "sema.cgo"
lock ( &semlock ) ;
for ( s=semfirst; s; s=s->next ) {
if ( s->addr == addr && s->g ) {
ready ( s->g ) ;
s->g = nil;
break;
}
}
unlock ( &semlock ) ;
}
#line 89 "sema.cgo"
static void
semsleep1 ( Sema *s )
{
lock ( &semlock ) ;
s->g = g;
unlock ( &semlock ) ;
}
#line 98 "sema.cgo"
static void
semsleepundo1 ( Sema *s )
{
lock ( &semlock ) ;
if ( s->g != nil ) {
s->g = nil;
} else {
#line 109 "sema.cgo"
if ( g->readyonstop == 0 )
* ( int32* ) 0x555 = 555;
g->readyonstop = 0;
}
unlock ( &semlock ) ;
}
#line 117 "sema.cgo"
static void
semsleep2 ( Sema *s )
{
USED ( s ) ;
g->status = Gwaiting;
gosched ( ) ;
}
#line 125 "sema.cgo"
static int32
cansemacquire ( uint32 *addr )
{
uint32 v;
#line 130 "sema.cgo"
while ( ( v = *addr ) > 0 )
if ( cas ( addr , v , v-1 ) )
return 1;
return 0;
}
#line 138 "sema.cgo"
void
semacquire ( uint32 *addr )
{
Sema s;
#line 144 "sema.cgo"
if ( cansemacquire ( addr ) )
return;
#line 152 "sema.cgo"
semqueue ( addr , &s ) ;
for ( ;; ) {
semsleep1 ( &s ) ;
if ( cansemacquire ( addr ) ) {
semsleepundo1 ( &s ) ;
break;
}
semsleep2 ( &s ) ;
}
semdequeue ( &s ) ;
semwakeup ( addr ) ;
}
#line 165 "sema.cgo"
void
semrelease ( uint32 *addr )
{
uint32 v;
#line 170 "sema.cgo"
for ( ;; ) {
v = *addr;
if ( cas ( addr , v , v+1 ) )
break;
}
semwakeup ( addr ) ;
}
void
runtime·Semacquire(uint32* addr)
{
#line 178 "sema.cgo"
semacquire(addr);
}
void
runtime·Semrelease(uint32* addr)
{
#line 182 "sema.cgo"
semrelease(addr);
}
|