Changeset 409 for trunk/kernel/syscalls
- Timestamp:
- Dec 20, 2017, 4:51:09 PM (5 years ago)
- Location:
- trunk/kernel/syscalls
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/syscalls/sys_fork.c
r408 r409 1 1 /* 2 * sys_fork.c - Fork the current process.2 * sys_fork.c - Kernel function implementing the "fork" system call. 3 3 * 4 4 * Authors Alain Greiner (2016,2017) -
trunk/kernel/syscalls/sys_kill.c
r124 r409 1 1 /* 2 * sys_kill.c :Send a signal to a given process.2 * sys_kill.c - Send a signal to a given process. 3 3 * 4 4 * Author Alain Greiner (2016,2017) … … 24 24 #include <kernel_config.h> 25 25 #include <hal_types.h> 26 #include <hal_irqmask.h> 26 27 #include <errno.h> 27 28 #include <thread.h> … … 36 37 uint32_t sig_id ) 37 38 { 39 uint32_t save_sr; // required to enable IRQs 40 41 #if CONFIG_SYSCALL_DEBUG 42 uint64_t tm_start; 43 uint64_t tm_end; 44 tm_start = hal_get_cycles(); 45 #endif 46 38 47 thread_t * this = CURRENT_THREAD; 39 48 process_t * process = this->process; 40 41 // check signal index42 if( (sig_id == 0) || (sig_id >= SIG_NR) )43 {44 printk("\n[ERROR] in %s : illegal signal = %d for thread %x in process %x\n",45 __FUNCTION__ , sig_id , this->trdid , process->pid );46 this->errno = EINVAL;47 return -1;48 }49 50 // get local pointer on local cluster manager51 cluster_t * cluster = LOCAL_CLUSTER;52 49 53 50 // get owner process cluster and lpid … … 55 52 lpid_t lpid = LPID_FROM_PID( pid ); 56 53 57 // check PID54 // check pid 58 55 if( (lpid >= CONFIG_MAX_PROCESS_PER_CLUSTER) || cluster_is_undefined( owner_cxy ) ) 59 56 { 60 57 printk("\n[ERROR] in %s : illegal target PID = %d for thread %x in process %x\n", 61 __FUNCTION__ , pid , this->trdid , process->pid );58 __FUNCTION__ , pid , this->trdid , pid ); 62 59 this->errno = EINVAL; 63 60 return -1; 64 61 } 65 62 66 // get extended pointers on copies root and lock 67 xptr_t root_xp = XPTR( owner_cxy , &cluster->pmgr.copies_root[lpid] ); 68 xptr_t lock_xp = XPTR( owner_cxy , &cluster->pmgr.copies_lock[lpid] ); 69 70 // take the lock protecting the copies 71 remote_spinlock_lock( lock_xp ); 72 73 // TODO the loop below sequencialize the RPCs 74 // they could be pipelined using a non-blocking RPC ... 75 76 // loop on the process decriptor copies 77 xptr_t iter_xp; 78 XLIST_FOREACH( root_xp , iter_xp ) 63 // check sig_id 64 if( (sig_id != SIGSTOP) && (sig_id != SIGCONT) && (sig_id != SIGKILL) ) 79 65 { 80 xptr_t process_xp = XLIST_ELEMENT( iter_xp , process_t , copies_list ); 81 cxy_t process_cxy = GET_CXY( process_xp ); 82 process_t * process_ptr = (process_t *)GET_PTR( process_xp ); 83 84 if( process_cxy == local_cxy ) // process copy is local 85 { 86 signal_rise( process_ptr , sig_id ); 87 } 88 else // process copy is remote 89 { 90 rpc_signal_rise_client( process_cxy , process_ptr , sig_id ); 91 } 66 printk("\n[ERROR] in %s : illegal signal type for thread %x in process %x\n", 67 __FUNCTION__ , sig_id , this->trdid , pid ); 68 this->errno = EINVAL; 69 return -1; 92 70 } 93 71 94 // release the lock 95 remote_spinlock_unlock( lock_xp ); 72 // enable IRQs 73 hal_enable_irq( &save_sr ); 74 75 // execute process_make_kill() function in owner cluster 76 if( local_cxy == owner_cxy ) // owner is local 77 { 78 process_make_kill( process , sig_id ); 79 } 80 else // owner is remote 81 { 82 rpc_process_make_kill_client( owner_cxy , process , sig_id ); 83 } 84 85 // restore IRQs 86 hal_restore_irq( save_sr ); 96 87 97 88 hal_fence(); 98 89 90 #if CONFIG_SYSCALL_DEBUG 91 tm_end = hal_get_cycles(); 92 syscall_dmsg("\n[DBG] %s exit : core[%x,%d] / thread %x in process %x / cycle %d\n" 93 "process %x killed / cost = %d\n", 94 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , this->process->pid , 95 tm_start , pid , (uint32_t)(tm_end - tm_start) ); 96 #endif 97 99 98 return 0; 100 99 -
trunk/kernel/syscalls/sys_read.c
r408 r409 25 25 #include <hal_types.h> 26 26 #include <hal_uspace.h> 27 #include <hal_irqmask.h> 27 28 #include <hal_special.h> 28 29 #include <errno.h> … … 35 36 // TODO: concurrent user page(s) munmap need to be handled [AG] 36 37 37 // instrumentation38 // TODO : remove these debug variables 38 39 extern uint32_t enter_sys_read; 39 40 extern uint32_t enter_devfs_move; … … 62 63 uint32_t nbytes; // number of bytes actually read 63 64 reg_t save_sr; // required to enable IRQs during syscall 64 uint32_t tm_start; 65 uint32_t tm_end; 66 67 tm_start = hal_get_cycles(); 68 69 #if CONFIG_READ_START 65 66 #if CONFIG_SYSCALL_DEBUG 67 uint32_t tm_start; 68 uint32_t tm_end; 69 tm_start = hal_get_cycles(); 70 #endif 71 72 #if CONFIG_READ_DEBUG 70 73 enter_sys_read = tm_start; 71 74 #endif … … 159 162 hal_fence(); 160 163 161 tm_end = hal_get_cycles(); 164 #if CONFIG_SYSCALL_DEBUG 165 tm_end = hal_get_cycles(); 166 syscall_dmsg("\n[DBG] %s exit : core[%x,%d] / thread %x in process %x / cycle %d\n" 167 "nbytes = %d / first byte = %c / file_id = %d / cost = %d\n", 168 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , this->process->pid , 169 tm_start , nbytes , *((char *)(intptr_t)paddr) , file_id , tm_end - tm_start ); 170 #endif 162 171 163 172 #if CONFIG_READ_DEBUG 164 173 exit_sys_read = tm_end; 165 174 166 printk("\n@@@@@@@@@@@@ timing ro read character %c\n"175 printk("\n@@@@@@@@@@@@ timing to read character %c\n" 167 176 " - enter_sys_read = %d / delta %d\n" 168 177 " - enter_devfs_move = %d / delta %d\n" … … 195 204 exit_sys_read , exit_sys_read - exit_devfs_move ); 196 205 #endif 197 198 syscall_dmsg("\n[DBG] %s : core[%x,%d] / thread %x in process %x / cycle %d\n"199 "nbytes = %d / first byte = %c / file_id = %d / cost = %d\n",200 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , this->process->pid ,201 tm_start , nbytes , *((char *)(intptr_t)paddr) , file_id , tm_end - tm_start );202 206 203 207 return nbytes; -
trunk/kernel/syscalls/sys_signal.c
r408 r409 38 38 this->errno = EINVAL; 39 39 return -1; 40 41 if((sig_id == 0) || (sig_id >= SIG_NR) || (sig_id == SIGKILL) || (sig_id == SIGSTOP))42 {43 printk("\n[ERROR] in %s : illega signal index = %d\n", __FUNCTION__ , sig_id );44 this->errno = EINVAL;45 return -1;46 }47 48 // register handler in signal manager for the calling process49 this->process->sig_mgr.sigactions[sig_id] = handler;50 51 signal_dmsg("\n[DBG] %s : handler @%x has been registred for signal %d\n",52 __FUNCTION__ , handler , sig_id );53 54 return 0;55 40 } 56 41 -
trunk/kernel/syscalls/sys_thread_exit.c
r408 r409 1 1 /* 2 * sys_thread_exit.c - terminates the execution of c urrentthread2 * sys_thread_exit.c - terminates the execution of calling thread 3 3 * 4 * Authors Ghassan Almaless (2008,2009,2010,2011,2012) 5 * Alain Greiner (2016,2017) 4 * Authors Alain Greiner (2016,2017) 6 5 * 7 6 * Copyright (c) UPMC Sorbonne Universites … … 24 23 25 24 #include <hal_types.h> 26 #include <hal_irqmask.h>27 25 #include <thread.h> 28 26 #include <core.h> 27 #include <vmm.h> 29 28 #include <scheduler.h> 30 29 #include <printk.h> 31 32 30 33 31 //////////////////////////////////////// 34 32 int sys_thread_exit( void * exit_value ) 35 33 { 36 thread_t * this = CURRENT_THREAD; 37 core_t * core = this->core; 38 reg_t irq_state; 34 paddr_t paddr; 35 error_t error; 39 36 40 // register the exit_value pointer in thread descriptor 41 this->exit_value = exit_value; 37 #if CONFIG_SYSCALL_DEBUG 38 uint32_t tm_start; 39 uint32_t tm_end; 40 tm_start = hal_get_cycles(); 41 #endif 42 42 43 // enter the join loop to wait the join if thread is joinable 44 if( (this->flags & THREAD_FLAG_DETACHED) == 0 ) 43 thread_t * this = CURRENT_THREAD; 44 process_t * process = this->process; 45 46 // check all locks released 47 if( !thread_can_yield() ) 48 { 49 printk("\n[ERROR] in %s : locks not released / thread %x in process %x\n", 50 __FUNCTION__, this->trdid, process->pid ); 51 this->errno = EINVAL; 52 return -1; 53 } 54 55 // register the exit_value pointer in this thread descriptor 56 this->join_value = exit_value; 57 58 if( (this->flags & THREAD_FLAG_DETACHED) == 0 ) // this thread is joinable 45 59 { 46 while( 1 ) 47 { 48 // take the lock protecting the flags 49 remote_spinlock_lock( XPTR( local_cxy, &this->flags_lock ) ); 60 // check exit_value in user space 61 error = vmm_v2p_translate( false , exit_value , &paddr ); 62 if( error ) 63 { 64 printk("\n[ERROR] in %s : illegal pointer = %x / thread %x in process %x\n", 65 __FUNCTION__ , (intptr_t)exit_value, this->trdid , process->pid ); 66 this->errno = EINVAL; 67 return -1; 68 } 50 69 51 // check the JOIN flag 52 if( this->flags & THREAD_FLAG_JOIN ) // parent made a join 53 { 54 // unblock the parent thread 55 thread_unblock( this->parent , THREAD_BLOCKED_JOIN ); 70 // take the lock protecting the join 71 remote_spinlock_lock( XPTR( local_cxy, &this->join_lock ) ); 56 72 57 // release the lock protecting the flags 58 remote_spinlock_unlock( XPTR( local_cxy, &this->flags_lock ) ); 73 if( this->flags & THREAD_FLAG_JOIN_DONE ) // parent thread arrived first 74 { 75 // unblock the parent thread 76 thread_unblock( this->join_xp , THREAD_BLOCKED_EXIT ); 59 77 60 // exit while 61 break; 62 } 63 else // no join done by parent thread 64 { 65 // set the EXIT flag 66 this->flags |= THREAD_FLAG_EXIT; 78 // reset the JOIN_DONE flag in this thread 79 this->flags &= ~THREAD_FLAG_JOIN_DONE; 67 80 68 // block this thread 69 thread_block( this , THREAD_BLOCKED_EXIT ); 81 // release the lock protecting the flags 82 remote_spinlock_unlock( XPTR( local_cxy, &this->join_lock ) ); 83 } 84 else // this thread arrived first 85 { 86 // block this thread 87 thread_block( this , THREAD_BLOCKED_JOIN ); 70 88 71 72 remote_spinlock_unlock( XPTR( local_cxy, &this->flags_lock ) );89 // release the lock protecting the flags 90 remote_spinlock_unlock( XPTR( local_cxy, &this->join_lock ) ); 73 91 74 // deschedule 75 sched_yield("waiting parent join"); 76 } 77 } 78 } 92 // deschedule 93 sched_yield( "WAITING JOIN" ); 94 } 95 } 79 96 80 // Release FPU if required 81 hal_disable_irq( &irq_state ); 82 if( core->fpu_owner == this ) core->fpu_owner = NULL; 83 hal_restore_irq( irq_state ); 97 #if CONFIG_SYSCALL_DEBUG 98 tm_end = hal_get_cycles(); 99 syscall_dmsg("\n[DBG] %s : core[%x,%d] / thread %x in process %x / cycle %d\n" 100 "thread %x killed / cost = %d\n", 101 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , this->process->pid , tm_start , 102 this->trdid , (uint32_t)(tm_end - tm_start) ); 103 #endif 84 104 85 // suicide 86 thread_kill( this ); 87 return 0; 105 // suicide using a rpc because a thread cannot kill itself 106 rpc_thread_kill_client( local_cxy , this ); 88 107 89 } // end sys_thread_exit() 108 return 0; // never executed but required by compiler 109 110 } // end sys_thread exit -
trunk/kernel/syscalls/sys_thread_join.c
r408 r409 40 40 cxy_t target_cxy; 41 41 ltid_t target_ltid; 42 uint32_t flags; // target thread flags 43 intptr_t value; // value returned by target thread44 paddr_t paddr; // required for vmm_v2p_translate()42 uint32_t target_blocked; // target thread blocked bit-vector 43 uint32_t target_flags; // target thread flags bit-bector 44 paddr_t paddr; // required for vmm_v2p_translate() 45 45 46 thread_t * this = CURRENT_THREAD;47 process_t * process = this->process;46 thread_t * this = CURRENT_THREAD; 47 process_t * process = this->process; 48 48 49 49 // get target thread ltid and cxy … … 89 89 90 90 // check target thread joinable 91 flags = hal_remote_lw( XPTR( target_cxy , &target_ptr->flags ) );92 if( flags & THREAD_FLAG_DETACHED )91 target_flags = hal_remote_lw( XPTR( target_cxy , &target_ptr->flags ) ); 92 if( target_flags & THREAD_FLAG_DETACHED ) 93 93 { 94 94 printk("\n[ERROR] in %s : target thread not joinable\n", __FUNCTION__ ); … … 100 100 if( target_ptr->signature != THREAD_SIGNATURE ) 101 101 { 102 printk("\n[PANIC] in %s : kernel stack overflow\n", __FUNCTION__ ); 103 hal_core_sleep(); 102 panic("\n[PANIC] in %s : kernel stack overflow\n", __FUNCTION__ ); 104 103 } 105 104 106 // wait target thread exit 107 while( 1 ) 105 // get the lock protecting the join in target thread 106 remote_spinlock_lock( XPTR( target_cxy , &target_ptr->join_lock ) ); 107 108 // get the blocked bit_vector from the target thread 109 target_blocked = hal_remote_lw( XPTR( target_cxy , &target_ptr->blocked ) ); 110 111 if( target_blocked & THREAD_BLOCKED_JOIN ) // target thread arrived first 108 112 { 109 // take the target thread lock protecting flags110 remote_spinlock_lock( XPTR( target_cxy , &target_ptr->flags_lock ));113 // unblock the target thread 114 thread_unblock( target_xp , THREAD_BLOCKED_JOIN ); 111 115 112 // get the remote thread flags113 flags = hal_remote_lw( XPTR( target_cxy , &target_ptr->flags) );116 // release the lock protecting flags 117 remote_spinlock_unlock( XPTR( target_cxy , &target_ptr->join_lock ) ); 114 118 115 // check the EXIT flag 116 if( flags & THREAD_FLAG_EXIT ) // target made an exit 117 { 118 // unblock the target thread 119 thread_unblock( target_xp , THREAD_BLOCKED_EXIT ); 119 // get the exit value from target thread 120 *exit_value = hal_remote_lpt( XPTR( target_cxy , &target_ptr->join_value ) ); 121 } 122 else // this thread arrived first 123 { 124 // register this thread extended pointer in target thread 125 hal_remote_swd( XPTR( target_cxy , &target_ptr->join_xp ) , 126 XPTR( local_cxy , this ) ); 120 127 121 // release the target thread lock protecting flags 122 remote_spinlock_unlock( XPTR( target_cxy , &target_ptr->flags_lock ) ); 128 // set the JOIN_DONE flag in target thread 129 hal_remote_atomic_or( XPTR( target_cxy , &target_ptr->flags ) , 130 THREAD_FLAG_JOIN_DONE ); 123 131 124 // exit while 125 break; 126 } 127 else // no exit done by target thread 128 { 129 // set the JOIN flag in target thread 130 hal_remote_atomic_or( XPTR( target_xp , &target_ptr->flags ) , 131 THREAD_BLOCKED_JOIN ); 132 // block this thread on BLOCKED_EXIT 133 thread_block( this , THREAD_BLOCKED_EXIT ); 132 134 133 // block this thread134 thread_block( this , THREAD_BLOCKED_JOIN);135 // release the lock protecting flags 136 remote_spinlock_unlock( XPTR( target_cxy , &target_ptr->join_lock ) ); 135 137 136 // release the target thread lock protecting flags 137 remote_spinlock_unlock( XPTR( target_cxy , &target_ptr->flags_lock ) ); 138 139 // deschedule 140 sched_yield("waiting child exit"); 141 } 138 // deschedule 139 sched_yield( "WAITING_EXIT" ); 140 141 // get the exit value from target thread when resume 142 *exit_value = hal_remote_lpt( XPTR( target_cxy , &target_ptr->join_value ) ); 142 143 } 143 144 144 // return exit_value from target thread descriptor145 value = (intptr_t)hal_remote_lpt( XPTR( target_cxy , &target_ptr->exit_value ) );146 *exit_value = (void *)value;147 145 return 0; 148 146 -
trunk/kernel/syscalls/sys_write.c
r408 r409 25 25 #include <hal_types.h> 26 26 #include <hal_uspace.h> 27 #include <hal_irqmask.h> 27 28 #include <hal_special.h> 28 29 #include <errno.h> … … 44 45 uint32_t nbytes; // number of bytes actually written 45 46 reg_t save_sr; // required to enable IRQs during syscall 46 uint32_t tm_start;47 uint32_t tm_end;48 47 49 tm_start = hal_get_cycles(); 48 #if CONFIG_SYSCALL_DEBUG 49 uint32_t tm_start; 50 uint32_t tm_end; 51 tm_start = hal_get_cycles(); 52 #endif 50 53 51 54 thread_t * this = CURRENT_THREAD; … … 136 139 hal_fence(); 137 140 138 tm_end = hal_get_cycles(); 139 141 #if CONFIG_SYSCALL_DEBUG 142 tm_end = hal_get_cycles(); 140 143 syscall_dmsg("\n[DBG] %s : core[%x,%d] / thread %x in process %x / cycle %d\n" 141 144 "nbytes = %d / first byte = %c / file_id = %d / cost = %d\n", 142 145 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , this->process->pid , 143 146 tm_start , nbytes , *((char *)(intptr_t)paddr) , file_id , tm_end - tm_start ); 147 #endif 144 148 145 149 return nbytes; -
trunk/kernel/syscalls/syscalls.h
r408 r409 40 40 * and makes the exit_value pointer available to any successful pthread_join() with the 41 41 * terminating thread. 42 ****************************************************************************************** 43 * @ exit_vallue : pointer to be returned to parent thread if thread is attached. 44 * @ return 0 if success / return -1 if failure. 42 * It actually set the THREAD_SIG_EXIT signal, set the THREAD_BLOCKED_GLOBAL bit in the 43 * thread descriptor and deschedule. 44 * The thread will be detached from its process, and the memory allocated to the thread 45 * descriptor will be released later by the scheduler. 46 ****************************************************************************************** 47 * @ exit_vallue : pointer to be returned to joining thread if thread is attached. 48 * @ return 0 if success / return -1 if all locks not released or illegal argument. 45 49 *****************************************************************************************/ 46 50 int sys_thread_exit( void * exit_value ); … … 87 91 * [4] This function detach a joinable thread. 88 92 ****************************************************************************************** 89 * @ trdid : thread identifier. i93 * @ trdid : thread identifier. 90 94 * @ return 0 if success / return -1 if failure. 91 95 *****************************************************************************************/ … … 93 97 94 98 /****************************************************************************************** 95 * [5] This slot is not used. 96 *****************************************************************************************/ 99 * [5] This function requests a target thread identified by its <trdid> argument 100 * to be cancelled. Depending on killer thread and target thread location, it calls 101 * the thread_kil() function or the rpc_thread_kill_client() function to do the work. 102 * It actually set the THREAD_SIG_KILL signal, set the THREAD_BLOCKED_GLOBAL bit in the 103 * target thread descriptor and return. 104 * The thread will be detached from its process, and the memory allocated to the thread 105 * descriptor will be released later by the scheduler. 106 ****************************************************************************************** 107 * @ trdid : thread identifier. 108 * @ return 0 if success / return -1 if illegal argument. 109 *****************************************************************************************/ 110 int sys_thread_cancel( trdid_t trdid ); 97 111 98 112 /****************************************************************************************** … … 158 172 * @ status : terminaison status (not used in present implementation). 159 173 *****************************************************************************************/ 160 voidsys_exit( uint32_t status );174 int sys_exit( uint32_t status ); 161 175 162 176 /******************************************************************************************
Note: See TracChangeset
for help on using the changeset viewer.