Пример #1
0
static int do_wait(struct ioq *q)
{
	struct epoll_event evts[32];
	const int timeout = waitq_next_deadline(&q->wait);
	int ret;
	int i;

	/* This can't fail for any reason but signal interruption */
	ret = epoll_wait(q->epoll_fd, evts, lengthof(evts), timeout);
	if (ret < 0) {
		if (syserr_last() == EINTR)
			return 0;
		return -1;
	}

	intr_ack(q);

	for (i = 0; i < ret; i++) {
		const struct epoll_event *e = &evts[i];
		struct ioq_fd *f = e->data.ptr;

		if (!f)
			continue;

		epoll_ctl(q->epoll_fd, EPOLL_CTL_DEL, f->fd, NULL);
		f->ready = e->events;

		thr_mutex_lock(&q->lock);
		f->flags &= ~(IOQ_FLAG_EPOLL | IOQ_FLAG_WAITING);
		mod_enqueue_nolock(q, f);
		thr_mutex_unlock(&q->lock);
	}

	return 0;
}
Пример #2
0
/** \internal
  * \brief  The Hybrid Threads initialization function.
  *
  * This function is the Hybrid Threads initialization function. This function
  * must be called before any other HThread's functionality is used.
  */
void hthread_init( void )
{
    int ret, i;
    hthread_t main_thread;
    hthread_t idle_thread;
    hthread_attr_t attrs;
    Huint status;

#ifdef HTHREADS_SMP
    int cpuid;
    if(_get_procid() == 0)
    {
        /* Default all stack values to NULL */
        for( i = 0; i < MAX_THREADS; i++ )  threads[ i ].stack	= NULL;

        /* Initialize the thread manager */ 
        _init_thread_manager();

        // Have to acknowledge the access interrupt generated because
        // spinlock and semaphore cores cause a failure
        // Hardcoded...FIXME
        intr_ack( 0x41200000, ACCESS_INTR_MASK );
        intr_ack( 0x41210000, ACCESS_INTR_MASK );

        // Must call this function again because we just reset the TM after
        // already reading CPUID = 0, therefore the next call to _init_cpuid()
        // will also return zero, giving two cpu's the id of zero
        _init_cpuid();

        // Setup the attributes for the idle thread
        attrs.detached	  = Htrue;
        attrs.stack_size  = HT_IDLE_STACK_SIZE;
        attrs.hardware    = Hfalse;
        attrs.stack_addr  = (void*)NULL;
        attrs.sched_param = 0x0000007F;           // Worst possible priority

        // Create the idle thread
        _create_system_thread( &idle_thread, &attrs, _idle_thread, NULL );
        TRACE_PRINTF( TRACE_INFO, TRACE_INIT, "HThread Init: (IDLE ID(PPC_%d)=%u)\n", _get_procid(), idle_thread );

        // Tell the hardware what the idle thread is
        _set_idle_thread( idle_thread, _get_procid() );

        //hthread_spin_lock(&(_sysc_lock));

        // Enable PPC specific interrupts
        //_arch_enable_intr();

        // Initialize the Architecture Specific Code
        TRACE_PRINTF( TRACE_INFO, TRACE_INIT, "Initializing Architecture...\n" );
        //_init_arch_specific( idle_thread );
        //_init_arch_specific();

        // Need to acquire lock here because bootstrap releases lock
        while(!_get_syscall_lock());

        _restore_context( 0 , idle_thread );
    }
    else
    {
        // Setup the attributes for the main thread
        attrs.detached	    = Htrue;                // The Main Thread is Detached
        attrs.stack_size    = HT_MAIN_STACK_SIZE;   // Stack Size for Main Thread
        attrs.hardware      = Hfalse;               // The Main Thread is not Hardware
        attrs.stack_addr    = (void*)0xFFFFFFFF;    // The Main Thread Already Has a Stack
        attrs.sched_param   = HT_DEFAULT_PRI;           // Middle of the Road Priority

        // Create the main thread
        _create_system_thread( &main_thread, &attrs, NULL, NULL );
        TRACE_PRINTF( TRACE_INFO, TRACE_INIT, "HThread Init: (MAIN ID(PPC_%d)=%u)\n", _get_procid(), main_thread );

        // Prevent the system from attempting to deallocate the main stack
        threads[ main_thread ].stack = NULL;

        // Add the main thread onto the ready-to-run queue
        status = _add_thread( main_thread );

        // Set the next thread to be the current thread. This should place
        // the main thread into the current thread register.
        status = _next_thread();

        // The main thread is not a new thread	
        threads[ main_thread ].newthread = Hfalse;

        // Setup the attributes for the idle thread
        attrs.detached	    = Htrue;
        attrs.stack_size    = HT_IDLE_STACK_SIZE;
        attrs.hardware      = Hfalse;
        attrs.stack_addr    = (void*)NULL;
        attrs.sched_param   = 0x0000007F;           // Worst possible priority

        // Create the idle thread
        _create_system_thread( &idle_thread, &attrs, _idle_thread, NULL );
        TRACE_PRINTF( TRACE_INFO, TRACE_INIT, "HThread Init: (IDLE ID(PPC_%d)=%u)\n", _get_procid(), idle_thread );

        // Tell the hardware what the idle thread is
        _set_idle_thread( idle_thread, _get_procid() );

        // Enable PPC specific interrupts
        //_arch_enable_intr();

        // Initialize the Architecture Specific Code
        TRACE_PRINTF( TRACE_INFO, TRACE_INIT, "Initializing Architecture...\n" );
        //_init_arch_specific( main_thread );
        //_init_arch_specific();

        // Enter into user mode
        //_arch_enter_user();

        _enable_preemption();
    }
#else
    // Initialize all of the thread stacks to NULL
    TRACE_PRINTF( TRACE_INFO, TRACE_INIT, "Initializing HThreads System...\n" );
    for( i = 0; i < MAX_THREADS; i++ )  threads[ i ].stack	= NULL;

    // Initialize the Thread Manager
    TRACE_PRINTF( TRACE_INFO, TRACE_INIT, "Initializing Thread Manager...\n" );
    _init_thread_manager();

    // Setup the attributes for the main thread
    attrs.detached	= Htrue;                // Main thread is detached
    attrs.stack_size	= HT_MAIN_STACK_SIZE;   // Stack size for main thread
    attrs.hardware      = Hfalse;               // Main thread is not hardware
    attrs.stack_addr    = (void*)0xFFFFFFFF;    // Main thread has a stack
    attrs.sched_param   = HT_DEFAULT_PRI;      // Middle of the road priority

    // Create the main thread
    ret = _create_system_thread( &main_thread, &attrs, NULL, NULL );
    TRACE_PRINTF( TRACE_INFO, TRACE_INIT, "HThread Init: (MAIN ID=%u)\n", main_thread );
    if( ret != SUCCESS )
    {
        TRACE_PRINTF(TRACE_FATAL, TRACE_INIT, "HThread Init: create main thread failed\n" );
        while(1);
    }

    // Initialize the Architecture Specific Code
    TRACE_PRINTF( TRACE_INFO, TRACE_INIT, "Initializing Architecture...\n" );
    
    //_init_arch_specific();

    // Prevent the system from attempting to deallocate the main stack
    threads[ main_thread ].stack = NULL;

    // Add the main thread onto the ready-to-run queue
    status = _add_thread( main_thread );

    // Set the next thread to be the current thread. This should place
    // the main thread into the current thread register.
    status = _next_thread();

    // Setup the attributes for the idle thread
    attrs.detached	= Htrue;
    attrs.stack_addr    = (void*)NULL;
    attrs.stack_size	= HT_IDLE_STACK_SIZE;

    // Create the idle thread
    ret = _create_system_thread( &idle_thread, &attrs, _idle_thread, NULL );
    TRACE_PRINTF( TRACE_INFO, TRACE_INIT, "HThread Init: (IDLE ID=%u)\n", idle_thread );
    if( ret != SUCCESS )
    {
        TRACE_PRINTF(TRACE_FATAL, TRACE_INIT, "HThread Init: create idle thread failed\n" );
        while(1);
    }

    // Tell the hardware what the idle thread is
    // FIXME - The CPUID is hardcoded, fix the manager/hardware.h file!
    _set_idle_thread( idle_thread , 0);

    // The main thread is not a new thread	
    threads[ main_thread ].newthread = Hfalse;

    // Enter into user mode
    //_arch_enable_intr();
    //_arch_enter_user();
#endif
}