예제 #1
0
파일: sysproc.c 프로젝트: hckjsnzf/selflib
/* Acquire semaphore (subtract 1). */
static int
semacquire(Segment *s, long *addr, int block)
{
	int acquired;
	Sema phore;

	if(canacquire(addr))
		return 1;
	if(!block)
		return 0;

	acquired = 0;
	semqueue(s, addr, &phore);
	for(;;){
		phore.waiting = 1;
		coherence();
		if(canacquire(addr)){
			acquired = 1;
			break;
		}
		if(waserror())
			break;
		sleep(&phore, semawoke, &phore);
		poperror();
	}
	semdequeue(s, &phore);
	coherence();	/* not strictly necessary due to lock in semdequeue */
	if(!phore.waiting)
		semwakeup(s, addr, 1);
	if(!acquired)
		nexterror();
	return 1;
}
예제 #2
0
파일: sysproc.c 프로젝트: Akheon23/nix-os
/* Acquire semaphore or timeout */
static int
tsemacquire(Segment *s, long *addr, ulong ms)
{
	int acquired;
	Sema phore;
	int timedout;
	ulong t;
	ulong tsemdbg;

	if(canacquire(addr))
		return 1;
	if(ms == 0)
		return 0;

	acquired = 0;
	timedout = 0;
	semqueue(s, addr, &phore);
	for(;;){
		phore.waiting = 1;
		coherence();
		if(canacquire(addr)){
			acquired = 1;
			break;
		}
		if(waserror())
			break;
		t = m->ticks;
		tsleep(&phore, semawoke, &phore, ms);
		if((tsemdbg = TK2MS(m->ticks - t)) >= ms){
			timedout = 1;
			poperror();
			break;
		}
		ms -= TK2MS(m->ticks - t);
		poperror();
	}
	semdequeue(s, &phore);
	coherence();	/* not strictly necessary due to lock in semdequeue */
	if(!phore.waiting)
		semwakeup(s, addr, 1);
	if(timedout)
		return 0;
	if(!acquired)
		nexterror();
	return 1;
}