/*-------------------------------------------- | Name: _syscall_pthread_exit | Description: | Parameters: none | Return Type: none | Comments: | See: ----------------------------------------------*/ int _syscall_pthread_exit(kernel_pthread_t* pthread_ptr, pid_t pid, void* data){ pthread_exit_t* pthread_exit_dt = (pthread_exit_t*)data; if(process_lst[pid]->pthread_ptr!=pthread_exit_dt->kernel_pthread) { //pthread sigqueue #ifdef __KERNEL_POSIX_REALTIME_SIGNALS //remove sigqueue objects explicitly only for annexe thread in other case "put all object" is used in process exit scenario. pthread_exit_dt->kernel_pthread->kernel_sigqueue.destructor( &pthread_exit_dt->kernel_pthread->kernel_sigqueue); #endif //it's a thread annexe _sys_pthread_cancel(pthread_exit_dt->kernel_pthread,pid); //__flush_syscall(pthread_ptr); return 0; }else{ //it's the main thread //all thread must be terminated exit_t exit_dt; exit_dt.pid = pid; exit_dt.status = 0; return _syscall_exit(pthread_ptr,pid,&exit_dt); } return 0; }
void _exit(int rc) { #ifndef NDEBUG _syscall_printf("\n Syscall _exit(%x)", rc); #endif _syscall_exit(rc); for(;;); }
/** \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; }