Esempio n. 1
0
// func selectnbsend(c chan any, elem *any) bool
//
// compiler implements
//
//	select {
//	case c <- v:
//		... foo
//	default:
//		... bar
//	}
//
// as
//
//	if selectnbsend(c, v) {
//		... foo
//	} else {
//		... bar
//	}
//
_Bool
runtime_selectnbsend(ChanType *t, Hchan *c, byte *val)
{
	bool res;

	res = chansend(t, c, val, false, runtime_getcallerpc(&t));
	return (_Bool)res;
}
Esempio n. 2
0
_Bool
reflect_chansend(ChanType *t, Hchan *c, byte *val, _Bool nb)
{
	bool selected;

	selected = chansend(t, c, val, !nb, runtime_getcallerpc(&t));
	return (_Bool)selected;
}
Esempio n. 3
0
File: chan.c Progetto: mm120/gcc
// func selectnbsend(c chan any, elem any) bool
//
// compiler implements
//
//	select {
//	case c <- v:
//		... foo
//	default:
//		... bar
//	}
//
// as
//
//	if selectnbsend(c, v) {
//		... foo
//	} else {
//		... bar
//	}
//
_Bool
runtime_selectnbsend(ChanType *t, Hchan *c, byte *p)
{
	bool res;

	runtime_chansend(t, c, p, &res, runtime_getcallerpc(&t));
	return res;
}
Esempio n. 4
0
// The compiler generates a call to __go_send_small to send a value 8
// bytes or smaller.
void
__go_send_small(ChanType *t, Hchan* c, uint64 val)
{
	union
	{
		byte b[sizeof(uint64)];
		uint64 v;
	} u;
	byte *v;

	u.v = val;
#ifndef WORDS_BIGENDIAN
	v = u.b;
#else
	v = u.b + sizeof(uint64) - t->__element_type->__size;
#endif
	chansend(t, c, v, true, runtime_getcallerpc(&t));
}
Esempio n. 5
0
File: chan.c Progetto: mm120/gcc
_Bool
reflect_chansend(ChanType *t, Hchan *c, uintptr val, _Bool nb)
{
	bool selected;
	bool *sp;
	byte *vp;

	if(nb) {
		selected = false;
		sp = (bool*)&selected;
	} else {
		selected = true;
		sp = nil;
	}
	if(__go_is_pointer_type(t->__element_type))
		vp = (byte*)&val;
	else
		vp = (byte*)val;
	runtime_chansend(t, c, vp, sp, runtime_getcallerpc(&t));
	return selected;
}
Esempio n. 6
0
// The compiler generates a call to __go_send_big to send a value
// larger than 8 bytes or smaller.
void
__go_send_big(ChanType *t, Hchan* c, byte* v)
{
	chansend(t, c, v, true, runtime_getcallerpc(&t));
}
Esempio n. 7
0
/*
 * generic single channel send/recv
 * if the bool pointer is nil,
 * then the full exchange will
 * occur. if pres is not nil,
 * then the protocol will not
 * sleep but return if it could
 * not complete.
 *
 * sleep can wake up with g->param == nil
 * when a channel involved in the sleep has
 * been closed.  it is easiest to loop and re-run
 * the operation; we'll see that it's now closed.
 */
static bool
chansend(ChanType *t, Hchan *c, byte *ep, bool block, void *pc)
{
	SudoG *sg;
	SudoG mysg;
	G* gp;
	int64 t0;
	G* g;

	g = runtime_g();

	if(raceenabled)
		runtime_racereadobjectpc(ep, t->__element_type, runtime_getcallerpc(&t), chansend);

	if(c == nil) {
		USED(t);
		if(!block)
			return false;
		runtime_park(nil, nil, "chan send (nil chan)");
		return false;  // not reached
	}

	if(runtime_gcwaiting())
		runtime_gosched();

	if(debug) {
		runtime_printf("chansend: chan=%p\n", c);
	}

	t0 = 0;
	mysg.releasetime = 0;
	if(runtime_blockprofilerate > 0) {
		t0 = runtime_cputicks();
		mysg.releasetime = -1;
	}

	runtime_lock(c);
	if(raceenabled)
		runtime_racereadpc(c, pc, chansend);
	if(c->closed)
		goto closed;

	if(c->dataqsiz > 0)
		goto asynch;

	sg = dequeue(&c->recvq);
	if(sg != nil) {
		if(raceenabled)
			racesync(c, sg);
		runtime_unlock(c);

		gp = sg->g;
		gp->param = sg;
		if(sg->elem != nil)
			runtime_memmove(sg->elem, ep, c->elemsize);
		if(sg->releasetime)
			sg->releasetime = runtime_cputicks();
		runtime_ready(gp);
		return true;
	}

	if(!block) {
		runtime_unlock(c);
		return false;
	}

	mysg.elem = ep;
	mysg.g = g;
	mysg.selectdone = nil;
	g->param = nil;
	enqueue(&c->sendq, &mysg);
	runtime_parkunlock(c, "chan send");

	if(g->param == nil) {
		runtime_lock(c);
		if(!c->closed)
			runtime_throw("chansend: spurious wakeup");
		goto closed;
	}

	if(mysg.releasetime > 0)
		runtime_blockevent(mysg.releasetime - t0, 2);

	return true;

asynch:
	if(c->closed)
		goto closed;

	if(c->qcount >= c->dataqsiz) {
		if(!block) {
			runtime_unlock(c);
			return false;
		}
		mysg.g = g;
		mysg.elem = nil;
		mysg.selectdone = nil;
		enqueue(&c->sendq, &mysg);
		runtime_parkunlock(c, "chan send");

		runtime_lock(c);
		goto asynch;
	}

	if(raceenabled)
		runtime_racerelease(chanbuf(c, c->sendx));

	runtime_memmove(chanbuf(c, c->sendx), ep, c->elemsize);
	if(++c->sendx == c->dataqsiz)
		c->sendx = 0;
	c->qcount++;

	sg = dequeue(&c->recvq);
	if(sg != nil) {
		gp = sg->g;
		runtime_unlock(c);
		if(sg->releasetime)
			sg->releasetime = runtime_cputicks();
		runtime_ready(gp);
	} else
		runtime_unlock(c);
	if(mysg.releasetime > 0)
		runtime_blockevent(mysg.releasetime - t0, 2);
	return true;

closed:
	runtime_unlock(c);
	runtime_panicstring("send on closed channel");
	return false;  // not reached
}
Esempio n. 8
0
File: print.c Progetto: 0day-ci/gcc
			runtime_printhex(va_arg(va, uint64));
			break;
		}
		lp = p+1;
	}
	if(p > lp)
		gwrite(lp, p-lp);

	//runtime_unlock(&debuglock);
}

void
runtime_printpc(void *p __attribute__ ((unused)))
{
	runtime_prints("PC=");
	runtime_printhex((uint64)(uintptr)runtime_getcallerpc(p));
}

void
runtime_printbool(_Bool v)
{
	if(v) {
		gwrite("true", 4);
		return;
	}
	gwrite("false", 5);
}

void
runtime_printbyte(int8 c)
{
Esempio n. 9
0
File: chan.c Progetto: mm120/gcc
// The compiler generates a call to __go_send_big to send a value
// larger than 8 bytes or smaller.
void
__go_send_big(ChanType *t, Hchan* c, byte* p)
{
	runtime_chansend(t, c, p, nil, runtime_getcallerpc(&t));
}