Example #1
0
unsigned
PutPipeTimed(Pipe_t *p, void *data, unsigned size, unsigned msecs)
{
	unsigned nbytes;
	char *d;

	if ( !size || !EnterMonitor(p->monitor) )
		return 0;

	// No se pueden escribir más bytes que el tamaño del pipe
	if ( size > p->size )
		size = p->size;

	// Si hay un timeout finito, calcular deadline.
	Time_t deadline = (msecs && msecs != FOREVER) ? Time() + msecs : 0;

	// Para que la escritura sea atómica, esperar a que haya lugar para escribir todos los bytes
	while ( (p->size - p->avail) < size ) 
	{
		// Desistir si es condicional, si no esperar
		if ( !msecs || !WaitConditionTimed(p->cond_put, msecs) )
		{
			LeaveMonitor(p->monitor);
			return 0;
		}
		// Si hay que seguir esperando con deadline, recalcular timeout
		if ( deadline && (p->size - p->avail) < size )
		{
			Time_t now = Time();
			msecs = now < deadline ? deadline - now : 0;
		}
	}

	// Hay por lo menos size bytes libres, escribir
	nbytes = size;
	d = data;
	while ( size-- )
	{
		*p->tail++ = *d++;
		if ( p->tail == p->end )
			p->tail = p->buf;
	}

	// Despertar eventuales lectores bloqueados
	if ( !p->avail )
		BroadcastCondition(p->cond_get);
	p->avail += nbytes;

	// Retornar cantidad de bytes escritos
	LeaveMonitor(p->monitor);
	return nbytes;
}
Example #2
0
unsigned
GetPipeTimed(Pipe_t *p, void *data, unsigned size, unsigned msecs)
{
	unsigned i, nbytes;
	char *d;

	if ( !size || !EnterMonitor(p->monitor) )
		return 0;

	// Si hay un timeout finito, calcular deadline.
	Time_t deadline = (msecs && msecs != FOREVER) ? Time() + msecs : 0;

	// Bloquearse si el pipe está vacío
	while ( !p->avail ) 
	{
		// Desistir si es condicional, si no esperar
		if ( !msecs || !WaitConditionTimed(p->cond_get, msecs) )
		{
			LeaveMonitor(p->monitor);
			return 0;
		}
		// Si hay que seguir esperando con deadline, recalcular timeout
		if ( deadline && !p->avail )
		{
			Time_t now = Time();
			msecs = now < deadline ? deadline - now : 0;
		}
	}

	// Leer lo que se pueda
	for ( nbytes = min(size, p->avail), d = data, i = 0 ; i < nbytes ; i++ )
	{
		*d++ = *p->head++;
		if ( p->head == p->end )
			p->head = p->buf;
	}

	// Despertar eventuales escritores bloqueados
	BroadcastCondition(p->cond_put);
	p->avail -= nbytes;

	// Retornar cantidad de bytes leídos
	LeaveMonitor(p->monitor);
	return nbytes;
}
Example #3
0
void
consumer(void *arg)
{
	char *name = arg;

	while ( true )
	{
		EnterMonitor(mon);
		while ( !key )
			WaitCondition(cond);
		printf("%s: key %c\n", name, key);
		key = 0;
		SignalCondition(cond);
		LeaveMonitor(mon);
	}
}
Example #4
0
bool				
WaitConditionTimed(Condition_t *cond, unsigned msecs)
{
	bool success;
	Monitor_t *mon = cond->monitor;

	if ( mon->owner != mt_curr_task )
		Panic("WaitConditionTimed %s: la tarea no posee el monitor %s", GetName(cond), GetName(cond->monitor));

	Atomic();
	LeaveMonitor(mon);
	success = WaitQueueTimed(&cond->queue, msecs);
	while ( !EnterMonitor(mon) )	// Hay que volver a tomar el monitor si o si
		;
	Unatomic();

	return success;
}
Example #5
0
int 
main(void)
{
	mon = CreateMonitor("dos");
	cond = CreateCondition("key", mon);

	Ready(CreateTask(consumer, 2000, "consumer", "consumer", DEFAULT_PRIO));

	while ( true )
	{
		EnterMonitor(mon);
		while ( key )
			WaitCondition(cond);
		key = getch();
		if ( key == 'S' || key == 's' )
			return 0;
		SignalCondition(cond);
		LeaveMonitor(mon);
	}
}