Changeset 23 for trunk/kernel/kern/signal.c
- Timestamp:
- Jun 18, 2017, 10:06:41 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/kern/signal.c
r5 r23 23 23 24 24 #include <hal_types.h> 25 #include <errno.h> 25 #include <hal_atomic.h> 26 #include <printk.h> 26 27 #include <thread.h> 27 #include <process.h> 28 #include <core.h> 28 #include <spinlock.h> 29 29 #include <signal.h> 30 31 ////////////////////////////////////// 32 void signal_rise( process_t * process, 33 uint32_t sig_id ) 34 { 35 // get the lock protecting the set of local threads 36 spinlock_lock( &process->th_lock ); 37 38 // loop on local threads 39 thread_t * thread; 40 uint32_t i; 41 for( i = 0 ; i < process->th_nr ; i++ ) 42 { 43 thread = process->th_tbl[i]; 44 hal_atomic_or( &thread->signals , (1 << sig_id) ); 45 46 signal_dmsg("\n[INFO] %s : thread %x in process %x received signal %d\n", 47 __FUNCTION__, thread->trdid , process->pid , sig_id ); 48 } 49 50 // release the lock 51 spinlock_unlock( &process->th_lock ); 52 53 } // end signal_rise() 54 55 /* 30 56 31 57 SIGNAL_HANDLER(kill_sigaction) 32 58 { 33 struct thread_s *this; 34 35 this = CURRENT_THREAD; 36 this->state = S_KERNEL; 59 thread_s * this = CURRENT_THREAD; 37 60 38 printk( INFO, "INFO: Recieved signal %d, pid %d, tid %x, core %d [ KILLED ]\n",61 printk("\n[INFO] %s : threadReceived signal %d, pid %d, tid %x, core %d [ KILLED ]\n", 39 62 sig, 40 63 this->process->pid, … … 45 68 } 46 69 47 /////////////////////////////////////////////// ///70 /////////////////////////////////////////////// 48 71 void signal_manager_init( process_t * process ) 49 72 { … … 53 76 } 54 77 55 ////////////////////////////////////// 56 void signal_rise( process_t * process, 57 uint32_t sig)78 79 ///////////////////////////////////// 80 void signal_notify( thread_t * this ) 58 81 { 59 thread_t * thread; 60 uint32_t i; 82 uint32_t sig_state; 83 uint32_t sig; 84 sig_mgr_t * sig_mgr; 85 uint32_t irq_state; 61 86 62 spinlock_lock( &process->th_lock ); 63 64 for( i = 0 ; i < process->th_nr ; i++ ) 65 { 66 thread = process->th_tbl[i]; 67 hal_atomic_or( &thread->signals , (1 << sig) ); 68 } 69 70 spinlock_unlock( &process->th_lock ); 71 72 sig_dmsg("\n[INFO] %s : %d threads have been signaled for process %d\n", 73 __FUNCTION__, process->th_nr , process->pid ); 74 75 } // end signal_rise() 76 77 /////////////////////////////////////////// 78 RPC_DECLARE( __signal_rise, \ 79 RPC_RET( RPC_RET_PTR(error_t, err)), \ 80 RPC_ARG( RPC_ARG_VAL(pid_t, pid), \ 81 RPC_ARG_VAL(uint32_t, sig)) \ 82 ) 83 { 84 process_t * process; 85 struct hnode_s *hnode; 86 87 /* Avoid killing process0 and init */ 88 /* FIXME: Zero should not be hard-coded but obtains with something like MAIN_KERN */ 89 if( ((pid == PID_MIN_GLOBAL) || (pid == PID_MIN_GLOBAL+1)) 90 && (current_cid == 0) ) 91 { 92 *err = EPERM; 93 sig_dmsg(1, "%s: can't kill process %u on cluster %u\n", \ 94 __FUNCTION__, PID_GET_LOCAL(pid), current_cid); 95 goto SYS_RISE_ERR_PID; 96 } 97 98 /* Step 1 : lock the process manager */ 99 processs_manager_lock(); 100 101 /* Step 2 : Get the process' address */ 102 /* Case 1 : current cluster is the anchor and the owner. */ 103 if ( PID_GET_CLUSTER(pid) == current_cid ) 104 { 105 sig_dmsg(1, "%s: process %u is in the processs manager array of cluster %u\n", \ 106 __FUNCTION__, pid, current_cid); 107 process = process_lookup(pid)->process; 108 109 } 110 else /* Case 2 : current cluster is not the anchor, so the struct 111 * process_s is in its hash table. 112 */ 113 { 114 sig_dmsg(1, "%s: process %u is in the processs manager hash table of cluster %u\n", \ 115 __FUNCTION__, pid, current_cid); 116 hnode = hfind(processs_manager_get_htable(), (void*)pid); 117 process = ( process_t*) container_of(hnode, \ 118 process_t, t_hnode); 119 } 120 121 /* Step 4 : check process' address */ 122 if ( process == NULL ) 123 { 124 *err = ESRCH; 125 goto SYS_RISE_ERR; 126 } 127 128 /* Step 5 : deliver signal */ 129 if((sig == SIGTERM) || (sig == SIGKILL)) 130 *err = signal_rise_all(process, sig); 131 else 132 *err = signal_rise_one(process, sig); 133 134 /* Step 6 : unlock processs manager */ 135 processs_manager_unlock(); 136 137 return; 138 139 SYS_RISE_ERR: 140 processs_manager_unlock(); 141 SYS_RISE_ERR_PID: 142 sig_dmsg(1, "%s: Cluster %u has not deliver signal %u to process %u (err %u)\n", \ 143 __FUNCTION__, current_cid, sig, err ); 144 145 return; 146 } 147 148 /////////////////////////////// 149 error_t sys_kill( pid_t pid, 150 uint32_t sig) 151 { 152 cxy_t owner_cxy; // process owner cluster 153 lpid_t owner_lpid; // local process identifier 154 xptr_t root_xp; // extended pointer on root of xlist of process copies 155 xptr_t lock_xp; // extended pointer on remote_spinlock protecting this list 156 xptr_t iter_xp; // iterator for process copies list 157 xptr_t process_xp; // local pointer on process copy 158 cxy_t process_cxy; // cluster of process copy 159 process_t * process_ptr; // local pointer on process copy 160 error_t error; 161 162 // get local pointer on local cluster manager 163 cluster_t * cluster = LOCAL_CLUSTER; 164 165 // get owner process cluster and lpid 166 owner_cxy = CXY_FROM_PID( pid ); 167 owner_lpid = LPID_FROM_PID( pid ); 168 169 // get extended pointers on copies root and lock 170 root_xp = XPTR( owner_cxy , &cluster->copies_root[lpid] ); 171 lock_xp = XPTR( owner_cxy , &cluster->copies_lock[lpid] ); 172 173 // take the lock protecting the copies 174 remote_spinlock_lock( lock_xp ); 175 176 // TODO the loop below sequencialize the RPCs 177 // they could be pipelined... 178 179 // traverse the list of copies 180 XLIST_FOREACH( root_xp , iter_xp ) 181 { 182 process_xp = XLIST_ELEMENT( iter_xp , process_t , copies_list ); 183 process_cxy = GET_CXY( process_xp ); 184 process_ptr = (process_t *)GET_PTR( process_xp ); 185 186 if( process_xy == local_cxy ) // process copy is local 187 { 188 error = signal_rise( process_ptr , sig ); 189 } 190 else // process copy is remote 191 { 192 rpc_signal_rise_client( process_cxy , process_ptr , sig ); 193 } 194 } 195 196 return 0; 197 } 198 199 //////////////////////////////////// 200 void signal_notify( thread_s * this) 201 { 202 register uint32_t sig_state; 203 register uint32_t sig; 204 register struct sig_mgr_s *sig_mgr; 205 uint32_t irq_state; 206 207 sig_state = this->info.sig_state & this->info.sig_mask; 87 sig_state = this->signals; 208 88 sig = 0; 209 89 … … 242 122 } 243 123 } 124 */
Note: See TracChangeset
for help on using the changeset viewer.