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; }
/** \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 }