Ejemplo n.º 1
0
void condition_broadcast(struct condition* c){
	struct thread* ready_thread = thread_dequeue(&c->waiting_threads);
	while(ready_thread){
		ready_thread->state = READY;
		thread_enqueue(&ready_list, ready_thread);
		ready_thread = thread_dequeue(&c->waiting_threads);
	}
};
Ejemplo n.º 2
0
void thread_manager_start()
/* call this once after launching at least one thread */
/* this only returns when all threads are blocked! */
{
	current = thread_dequeue( &readylist );
	if (current == thread_null) {
		/* crisis */
		fprintf(stderr, "Thread manager start failure, no threads!\n");
		exit(-1);
	}
	if (_setjmp( thread_death )) {
		/* comes here when _longjmp( thread_death, 1 ) done */
		fprintf(stderr,
			"Thread manager terminated, %s!\n", thread_error );
		if (mem_to_free != (void *)0 ) {
			/* see comments below */
			free( mem_to_free );
		}
	} else {
		/* we will come back here whenever we need to deallocate */
		(void) _setjmp( go_free_it );

		if (mem_to_free != (void *)0 ) {
			/* it's not safe to call free() anywhere but on the
			   real stack, so once the thread manager is running,
			   this is the only safe place to call it!
		        */
			free( mem_to_free );
			mem_to_free = (void *)0;
		}

		_longjmp( current->state, 1 );
	}
}
Ejemplo n.º 3
0
void condition_signal(struct condition* c){
	struct thread* ready_thread = thread_dequeue(&c->waiting_threads);
	if(ready_thread){
		ready_thread->state = READY;
		thread_enqueue(&ready_list, ready_thread);
	}
};
Ejemplo n.º 4
0
/**
 * \brief Called on the inter-disp handler thread, when another thread
 * on this dispatcher wants to wakeup a thread on a foreign dispatcher.
 */
static void handle_wakeup_on(void *arg)
{
    struct domain_state *domain_state = get_domain_state();
    errval_t err;

    assert(domain_state != NULL);

    // Dequeue all (disable to ensure mutual exclusion -- per dispatcher)
    for(;;) {
        struct thread *thread = NULL;

        dispatcher_handle_t disp = disp_disable();
        if(domain_state->remote_wakeup_queue != NULL) {
            thread = thread_dequeue(&domain_state->remote_wakeup_queue);
        }
        disp_enable(disp);

        // Break if queue empty
        if(thread == NULL) {
            break;
        }

        // XXX: Hack
        /* coreid_t core_id = disp_handle_get_core_id(thread->disp); */
        coreid_t core_id = thread->coreid;

        assert(domain_state->b[core_id] != NULL);

        struct interdisp_binding *b = domain_state->b[core_id];
        err = b->tx_vtbl.wakeup_thread(b, NOP_CONT, (genvaddr_t)(uintptr_t)thread);
        if (err_is_fail(err)) {
            USER_PANIC_ERR(err, "wakeup_thread");
        }
    }
}
Ejemplo n.º 5
0
void thread_relinquish()
/* call this within a thread to allow scheduling of a new thread */
{
	if (_setjmp( current->state ) == 0) {
		thread_enqueue( current, &readylist );
		current = thread_dequeue( &readylist );
		_longjmp( current->state, 1 );
	}
}
Ejemplo n.º 6
0
void thread_signal( struct thread_semaphore * s )
/* call this within a thread to signal a semaphore */
{
	struct thread * t = thread_dequeue( &s->queue );
	if (t == thread_null) {
		s->count++;
	} else {
		thread_enqueue( t, &readylist );
	}
}
Ejemplo n.º 7
0
void mutex_unlock(struct mutex * m){
	if(is_empty(&m->waiting_threads)){
		m->held = 0;
	}else{
		struct thread* temp = thread_dequeue(&m->waiting_threads);
		if(temp){
			temp->state = READY;
			thread_enqueue(&ready_list, temp);
		}
	}
};
Ejemplo n.º 8
0
static int thread_read( UThread* ut, UBuffer* port, UCell* dest, int part )
{
    UBuffer tbuf;
    ThreadExt* ext = (ThreadExt*) port->ptr.v;
    ThreadQueue* queue;
    (void) part;

    tbuf.type = 0;

    queue = (port->SIDE == SIDE_A) ? &ext->B : &ext->A;

    if( ! queue->readIt )
        readEvent( queue );     // Waits until data is available.

    mutexLock( queue->mutex );
    while( queue->readIt >= queue->buf.used )
    {
        if( condWaitF( queue->cond, queue->mutex ) )
        {
            mutexUnlock( queue->mutex );
            goto waitError;
        }
    }
    queue->readIt = thread_dequeue( &queue->buf, queue->readIt, dest, &tbuf );
    mutexUnlock( queue->mutex );

    if( tbuf.type )
    {
        UIndex bufN;

        dest->series.buf = UR_INVALID_BUF;
        ur_genBuffers( ut, 1, &bufN );
        dest->series.buf = bufN;

        memCpy( ur_buffer( bufN ), &tbuf, sizeof(UBuffer) );
    }
    else
    {
        int type = ur_type(dest);
        if( ur_isWordType(type) )
        {
            if( ur_binding(dest) == UR_BIND_THREAD )
                ur_unbind(dest);
        }
    }

    return UR_OK;

waitError:

    return ur_error( ut, UR_ERR_INTERNAL, "thread_read condWait failed" );
}
Ejemplo n.º 9
0
// yield is very similar to thread_fork, with the main difference being that 
// it is pulling the next thread to run off of the ready list instead of creating it. yield should:
void yield(){
	// If the current thread is not DONE, set its state to READY and enqueue it on the ready list.
	if(current_thread->state != DONE && current_thread->state != BLOCKED){
		current_thread->state = READY;
		thread_enqueue(&ready_list, current_thread);
	}
	// Dequeue the next thread from the ready list and set its state to RUNNING.
	struct thread* next_thread = thread_dequeue(&ready_list);
	next_thread->state = RUNNING;
	// Save a pointer to the current thread in a temporary variable, then set the current thread to the next thread.
	struct thread* temp = current_thread;
	current_thread = next_thread;
	// Call thread_switch with the old current thread as old and the new current thread as new.
	thread_switch(temp, current_thread);
};
Ejemplo n.º 10
0
void thread_exit()
/* call this within a thread to terminate that thread */
{
	/* we can't deallocate, so we schedule this thread for deallocation */
	mem_to_free = (void *)current;

	/* now, get the next thread to run */
	current = thread_dequeue( &readylist );
	if (current == thread_null) {
		/* crisis */
		thread_error = "ready list empty";
		_longjmp( thread_death, 1 );
	}

	_longjmp( go_free_it, 1 );
}
Ejemplo n.º 11
0
void thread_wait( struct thread_semaphore * s )
/* call this within a thread to block on a semaphore */
{
	if (s->count > 0) {
		s->count--;
        } else {
		if (_setjmp( current->state ) == 0) {
			thread_enqueue( current, &s->queue );
			current = thread_dequeue( &readylist );
			if (current == thread_null) {
				/* crisis */
				thread_error = "possible deadlock";

				_longjmp( thread_death, 1 );
			}
			_longjmp( current->state, 1 );
		}
	}
}
Ejemplo n.º 12
0
void yield()
{
	/* If the current thread is not DONE, set its state to READY and 
	enqueue it on the ready list. */
	if (current_thread->state != DONE) {
		current_thread->state = READY;
		thread_enqueue(&ready_list, current_thread);
//printf("YIELD: current thread not finished, back on queue\n");
	}

	// Dequeue the next thread from the ready list and set its state to RUNNING.
	thread *next_thread = thread_dequeue(&ready_list);

	/* Save a pointer to the current thread in a temporary variable, 
	then set the current thread to the next thread. */
	thread *temp = current_thread;
	current_thread = next_thread;
	
	/* Call thread_switch with the old current thread as old and 
	the new current thread as new. */
	thread_switch(temp, current_thread);
//printf("YIELD: Running dequeued thread\n");
}