void* _bootstrap_thread( hthread_start_t func, void *arg ) { void *ret; #ifdef HTHREADS_SMP while(!_release_syscall_lock()); #endif // Get start time hthread_time_t start = hthread_time_get(); // Invoke the start function and grab the return value ret = func( arg ); // Get stop time and write execution time in TCB structure hthread_time_t stop = hthread_time_get(); Huint tid = hthread_self(); threads[tid].execution_time = stop-start; // Decrement the counter. It is safer to do this // after hthread_exit but since we don't return // from this call, we will do it here. thread_counter--; // Exit the thread using the return value hthread_exit( ret ); // This statement should never be reached return NULL; }
/** \internal * \brief The exception handler for the system call exception. * * This function is registered at initialization time to be the system * call exception handler. It calls one of several functions based on the * system call number and returns the results of the system call back * to the caller by way of the param1 variable in the system call * data structure. */ void* _system_call_handler(Huint c,void *p2,void *p3,void *p4,void *p5,void *p6) { void *ret; if (c > 16) { /* Pseudo assembler instructions */ #define stringify(s) tostring(s) #define tostring(s) #s #define mfgpr(rn) ({ unsigned int _rval; \ __asm__ __volatile__ ( \ "or\t%0,r0," stringify(rn) "\n" : "=d"(_rval) \ ); \ _rval; \ }) unsigned int temp_reg; temp_reg = mfgpr(r15); printf("[TID = %u] Illegal Syscall ID 0x%08x, r15 = 0x%08x\n",_current_thread(),c,temp_reg); while(1); } #ifdef HTHREADS_SMP while( !_get_syscall_lock() ); #endif hprofile_hist_capture( SYSCALL, SCTYPE, c ); switch( c ) { case HTHREAD_SYSCALL_CREATE: ret = (void*)_syscall_create( (hthread_t*)p2, (hthread_attr_t*)p3, (hthread_start_t)p4, p5 ); break; case HTHREAD_SYSCALL_JOIN: ret = (void*)_syscall_join( (hthread_t)p2, (void**)p3 ); break; case HTHREAD_SYSCALL_DETACH: ret = (void*)_syscall_detach( (hthread_t)p2 ); break; case HTHREAD_SYSCALL_YIELD: ret = (void*)_syscall_yield(); break; case HTHREAD_SYSCALL_EXIT: _syscall_exit( p2 ); ret = NULL; break; case HTHREAD_SYSCALL_CURRENTID: ret = (void*)_syscall_current_id(); break; case HTHREAD_SYSCALL_SETPRI: ret = (void*)_syscall_set_schedparam( (hthread_t)p2, (Huint)p3 ); break; case HTHREAD_SYSCALL_GETPRI: ret = (void*)_syscall_get_schedparam( (hthread_t)p2, (Hint*)p3 ); break; case HTHREAD_SYSCALL_MUTEX_LOCK: ret = (void*)_syscall_mutex_lock((hthread_mutex_t*)p2); break; case HTHREAD_SYSCALL_MUTEX_UNLOCK: ret = (void*)_syscall_mutex_unlock((hthread_mutex_t*)p2); break; case HTHREAD_SYSCALL_MUTEX_TRYLOCK: ret = (void*)_syscall_mutex_trylock((hthread_mutex_t*)p2); break; case HTHREAD_SYSCALL_COND_WAIT: ret = (void*)_syscall_cond_wait((hthread_cond_t*)p2, (hthread_mutex_t*)p3); break; case HTHREAD_SYSCALL_COND_SIGNAL: ret = (void*)_syscall_cond_signal((hthread_cond_t*)p2); break; case HTHREAD_SYSCALL_COND_BROADCAST: ret = (void*)_syscall_cond_broadcast((hthread_cond_t*)p2); break; case HTHREAD_SYSCALL_INTRASSOC: ret = (void*)_syscall_intr_assoc( (Huint)p2 ); break; case HTHREAD_SYSCALL_SCHED: ret = (void*)_syscall_sched(); break; default: printf("***** Bad Syscall ID (0x%08x) ******\n",c); ret = (void*)EINVAL; break; } #ifdef HTHREADS_SMP while( !_release_syscall_lock() ); #endif return ret; }