Changeset 408 for trunk/kernel/kern/rpc.c
- Timestamp:
- Dec 5, 2017, 4:20:07 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/kern/rpc.c
r407 r408 49 49 { 50 50 &rpc_pmem_get_pages_server, // 0 51 &rpc_process_ pid_alloc_server, // 152 &rpc_process_ exec_server,// 251 &rpc_process_make_exec_server, // 1 52 &rpc_process_make_fork_server, // 2 53 53 &rpc_process_kill_server, // 3 54 54 &rpc_thread_user_create_server, // 4 … … 78 78 &rpc_vmm_create_vseg_server, // 26 79 79 &rpc_sched_display_server, // 27 80 &rpc_ undefined,// 2880 &rpc_vmm_set_cow_server, // 28 81 81 &rpc_undefined, // 29 82 82 }; … … 148 148 149 149 ///////////////////////////////////////////////////////////////////////////////////////// 150 // [1] Marshaling functions attached to RPC_PROCESS_PID_ALLOC 151 ///////////////////////////////////////////////////////////////////////////////////////// 152 153 ////////////////////////////////////////////////// 154 void rpc_process_pid_alloc_client( cxy_t cxy, 155 process_t * process, // in 156 error_t * error, // out 157 pid_t * pid ) // out 158 { 159 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 160 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 161 CURRENT_THREAD->core->lid , hal_time_stamp() ); 162 163 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 164 165 // initialise RPC descriptor header 166 rpc_desc_t rpc; 167 rpc.index = RPC_PROCESS_PID_ALLOC; 168 rpc.response = 1; 169 170 // set input arguments in RPC descriptor 171 rpc.args[0] = (uint64_t)(intptr_t)process; 172 173 // register RPC request in remote RPC fifo (blocking function) 174 rpc_send_sync( cxy , &rpc ); 175 176 // get output arguments RPC descriptor 177 *pid = (pid_t)rpc.args[1]; 178 *error = (error_t)rpc.args[2]; 179 180 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 181 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 182 CURRENT_THREAD->core->lid , hal_time_stamp() ); 183 } 184 185 ////////////////////////////////////////////// 186 void rpc_process_pid_alloc_server( xptr_t xp ) 187 { 188 process_t * process; // input : client process descriptor 189 error_t error; // output : error status 190 pid_t pid; // output : process identifier 191 192 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 193 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 194 CURRENT_THREAD->core->lid , hal_time_stamp() ); 195 196 // get client cluster identifier and pointer on RPC descriptor 197 cxy_t client_cxy = (cxy_t)GET_CXY( xp ); 198 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp ); 199 200 // get input argument from client RPC descriptor 201 process = (process_t*)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) ); 202 203 // call local pid allocator 204 xptr_t xp_process = XPTR( client_cxy , process ); 205 error = cluster_pid_alloc( xp_process , &pid ); 206 207 // set output arguments into client RPC descriptor 208 hal_remote_sw( XPTR( client_cxy , &desc->args[0] ) , (uint64_t)error ); 209 hal_remote_sw( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)pid ); 210 211 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 212 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 213 CURRENT_THREAD->core->lid , hal_time_stamp() ); 214 } 215 216 217 ///////////////////////////////////////////////////////////////////////////////////////// 218 // [2] Marshaling functions attached to RPC_PROCESS_EXEC 219 ///////////////////////////////////////////////////////////////////////////////////////// 220 221 //////////////////////////////////////////////// 222 void rpc_process_exec_client( cxy_t cxy, 223 exec_info_t * info, // in 224 error_t * error ) // out 225 { 226 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 227 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 228 CURRENT_THREAD->core->lid , hal_time_stamp() ); 229 230 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 231 232 // initialise RPC descriptor header 233 rpc_desc_t rpc; 234 rpc.index = RPC_PROCESS_EXEC; 150 // [1] Marshaling functions attached to RPC_PROCESS_MAKE_EXEC 151 ///////////////////////////////////////////////////////////////////////////////////////// 152 153 ///////////////////////////////////////////////////// 154 void rpc_process_make_exec_client( cxy_t cxy, 155 exec_info_t * info, // in 156 error_t * error ) // out 157 { 158 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 159 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 160 CURRENT_THREAD->core->lid , hal_time_stamp() ); 161 162 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 163 164 // initialise RPC descriptor header 165 rpc_desc_t rpc; 166 rpc.index = RPC_PROCESS_MAKE_EXEC; 235 167 rpc.response = 1; 236 168 … … 249 181 } 250 182 251 ///////////////////////////////////////// 252 void rpc_process_ exec_server( xptr_t xp )183 ////////////////////////////////////////////// 184 void rpc_process_make_exec_server( xptr_t xp ) 253 185 { 254 186 exec_info_t * ptr; // local pointer on remote exec_info structure … … 283 215 } 284 216 217 ///////////////////////////////////////////////////////////////////////////////////////// 218 // [2] Marshaling functions attached to RPC_PROCESS_MAKE_FORK 219 ///////////////////////////////////////////////////////////////////////////////////////// 220 221 /////////////////////////////////////////////////// 222 void rpc_process_make_fork_client( cxy_t cxy, 223 xptr_t ref_process_xp, // in 224 xptr_t parent_thread_xp, // in 225 pid_t * child_pid, // out 226 thread_t ** child_thread_ptr, // out 227 error_t * error ) // out 228 { 229 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 230 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 231 CURRENT_THREAD->core->lid , hal_time_stamp() ); 232 233 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 234 235 // initialise RPC descriptor header 236 rpc_desc_t rpc; 237 rpc.index = RPC_PROCESS_MAKE_FORK; 238 rpc.response = 1; 239 240 // set input arguments in RPC descriptor 241 rpc.args[0] = (uint64_t)(intptr_t)ref_process_xp; 242 rpc.args[1] = (uint64_t)(intptr_t)parent_thread_xp; 243 244 // register RPC request in remote RPC fifo (blocking function) 245 rpc_send_sync( cxy , &rpc ); 246 247 // get output arguments from RPC descriptor 248 *child_pid = (pid_t)rpc.args[2]; 249 *child_thread_ptr = (thread_t *)(intptr_t)rpc.args[3]; 250 *error = (error_t)rpc.args[4]; 251 252 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 253 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 254 CURRENT_THREAD->core->lid , hal_time_stamp() ); 255 } 256 257 ////////////////////////////////////////////// 258 void rpc_process_make_fork_server( xptr_t xp ) 259 { 260 xptr_t ref_process_xp; // extended pointer on reference parent process 261 xptr_t parent_thread_xp; // extended pointer on parent thread 262 pid_t child_pid; // child process identifier 263 thread_t * child_thread_ptr; // local copy of exec_info structure 264 error_t error; // local error status 265 266 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 267 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 268 CURRENT_THREAD->core->lid , hal_time_stamp() ); 269 270 // get client cluster identifier and pointer on RPC descriptor 271 cxy_t client_cxy = (cxy_t)GET_CXY( xp ); 272 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp ); 273 274 // get input arguments from cient RPC descriptor 275 ref_process_xp = (xptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) ); 276 parent_thread_xp = (xptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) ); 277 278 // call local kernel function 279 error = process_make_fork( ref_process_xp, 280 parent_thread_xp, 281 &child_pid, 282 &child_thread_ptr ); 283 284 // set output argument into client RPC descriptor 285 hal_remote_swd( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)child_pid ); 286 hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)(intptr_t)child_thread_ptr ); 287 hal_remote_swd( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)error ); 288 289 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 290 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 291 CURRENT_THREAD->core->lid , hal_time_stamp() ); 292 } 285 293 286 294 ///////////////////////////////////////////////////////////////////////////////////////// … … 1800 1808 } 1801 1809 1810 ///////////////////////////////////////////////////////////////////////////////////////// 1811 // [28] Marshaling functions attached to RPC_VMM_SET_COW 1812 ///////////////////////////////////////////////////////////////////////////////////////// 1813 1814 ///////////////////////////////////////////// 1815 void rpc_vmm_set_cow_client( cxy_t cxy, 1816 process_t * process ) 1817 { 1818 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 1819 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1820 CURRENT_THREAD->core->lid , hal_time_stamp() ); 1821 1822 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 1823 1824 // initialise RPC descriptor header 1825 rpc_desc_t rpc; 1826 rpc.index = RPC_VMM_SET_COW; 1827 rpc.response = 1; 1828 1829 // set input arguments in RPC descriptor 1830 rpc.args[0] = (uint64_t)(intptr_t)process; 1831 1832 // register RPC request in remote RPC fifo (blocking function) 1833 rpc_send_sync( cxy , &rpc ); 1834 1835 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 1836 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1837 CURRENT_THREAD->core->lid , hal_time_stamp() ); 1838 } 1839 1840 //////////////////////////////////////// 1841 void rpc_vmm_set_cow_server( xptr_t xp ) 1842 { 1843 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 1844 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1845 CURRENT_THREAD->core->lid , hal_time_stamp() ); 1846 1847 process_t * process; 1848 1849 // get client cluster identifier and pointer on RPC descriptor 1850 cxy_t cxy = (cxy_t)GET_CXY( xp ); 1851 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp ); 1852 1853 // get input arguments from client RPC descriptor 1854 process = (process_t *)(intptr_t)hal_remote_lpt( XPTR(cxy , &desc->args[0])); 1855 1856 // call local kernel function 1857 vmm_set_cow( process ); 1858 1859 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 1860 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1861 CURRENT_THREAD->core->lid , hal_time_stamp() ); 1862 } 1863 1802 1864 /***************************************************************************************/ 1803 1865 /************ Generic functions supporting RPCs : client side **************************/ … … 1835 1897 __FUNCTION__ , local_cxy , server_cxy ); 1836 1898 1837 if( thread_can_yield() ) sched_yield( );1899 if( thread_can_yield() ) sched_yield("RPC fifo full"); 1838 1900 } 1839 1901 } … … 1872 1934 1873 1935 thread_block( this , THREAD_BLOCKED_RPC ); 1874 sched_yield( );1936 sched_yield("client blocked on RPC"); 1875 1937 1876 1938 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %s resumes after RPC completion\n", … … 1959 2021 1960 2022 // interrupted thread deschedule always 1961 sched_yield( );2023 sched_yield("IPI received"); 1962 2024 1963 2025 grpc_dmsg("\n[DBG] %s : core[%x,%d] / interrupted thread %s resume / cycle %d\n", … … 2079 2141 2080 2142 // deschedule without blocking 2081 sched_yield( );2143 sched_yield("RPC fifo empty or too much work"); 2082 2144 2083 2145 grpc_dmsg("\n[DBG] %s : core[%x,%d] (RPC thread %x) resumes / cycle %d\n", … … 2089 2151 2090 2152 2091 2092 2093 2094 2095 2096 2097 2098 /* deprecated [AG] 29/09/20172099 2100 ////////////////////////////////////////////////////2101 error_t rpc_activate_thread( remote_fifo_t * rpc_fifo )2102 {2103 core_t * core;2104 thread_t * thread;2105 thread_t * this;2106 scheduler_t * sched;2107 error_t error;2108 bool_t found;2109 reg_t sr_save;2110 2111 2112 this = CURRENT_THREAD;2113 core = this->core;2114 sched = &core->scheduler;2115 found = false;2116 2117 assert( (this->trdid == rpc_fifo->owner) , __FUNCTION__ ,2118 "calling thread is not RPC_FIFO owner\n" );2119 2120 // makes the calling thread not preemptable2121 // during activation / creation of the RPC thread2122 hal_disable_irq( &sr_save );2123 2124 grpc_dmsg("\n[DBG] %s : core[%x,%d] enter at cycle %d\n",2125 __FUNCTION__ , local_cxy , core->lid , hal_time_stamp() );2126 2127 // search one non blocked RPC thread2128 list_entry_t * iter;2129 LIST_FOREACH( &sched->k_root , iter )2130 {2131 thread = LIST_ELEMENT( iter , thread_t , sched_list );2132 if( (thread->type == THREAD_RPC) && (thread->blocked == 0 ) )2133 {2134 found = true;2135 break;2136 }2137 }2138 2139 if( found == false ) // create new RPC thread2140 {2141 error = thread_kernel_create( &thread,2142 THREAD_RPC,2143 &rpc_thread_func,2144 NULL,2145 core->lid );2146 if( error )2147 {2148 hal_restore_irq( sr_save );2149 printk("\n[ERROR] in %s : no memory for new RPC thread in cluster %x\n",2150 __FUNCTION__ , local_cxy );2151 return ENOMEM;2152 }2153 2154 // unblock thread2155 thread->blocked = 0;2156 2157 // update core descriptor counter2158 hal_atomic_add( &LOCAL_CLUSTER->rpc_threads , 1 );2159 2160 grpc_dmsg("\n[DBG] %s : core [%x,%d] creates RPC thread %x at cycle %d\n",2161 __FUNCTION__ , local_cxy , core->lid , thread->trdid , hal_time_stamp() );2162 2163 }2164 else // create a new RPC thread2165 {2166 2167 grpc_dmsg("\n[DBG] %s : core[%x,%d] activates RPC thread %x at cycle %d\n",2168 __FUNCTION__ , local_cxy , core->lid , thread->trdid , hal_time_stamp() );2169 2170 }2171 2172 // update rpc_fifo owner2173 rpc_fifo->owner = thread->trdid;2174 2175 // current thread deschedule2176 sched_yield();2177 2178 // restore IRQs for the calling thread2179 hal_restore_irq( sr_save );2180 2181 // return success2182 return 0;2183 2184 } // end rpc_activate_thread()2185 2186 ////////////////2187 void rpc_check()2188 {2189 thread_t * this = CURRENT_THREAD;2190 remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo;2191 error_t error;2192 2193 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %x / enter at cycle %d\n",2194 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , hal_time_stamp() );2195 2196 // calling thread does nothing if light lock already taken or FIFO empty2197 if( (rpc_fifo->owner != 0) || (local_fifo_is_empty( &rpc_fifo->fifo )) )2198 {2199 2200 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %x / exit do nothing at cycle %d\n",2201 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , hal_time_stamp() );2202 2203 return;2204 }2205 2206 // try to take the light lock, and activates an RPC thread if success2207 if( hal_atomic_test_set( &rpc_fifo->owner , this->trdid ) )2208 {2209 error = rpc_activate_thread( rpc_fifo );2210 2211 if( error ) // cannot activate an RPC_THREAD2212 {2213 rpc_fifo->owner = 0;2214 2215 printk("\n[ERROR] in %s : no memory to create a RPC thread for core %d"2216 " in cluster %x => do nothing\n",2217 __FUNCTION__ , CURRENT_CORE->lid , local_cxy );2218 }2219 2220 return;2221 }2222 else // light lock taken by another thread2223 {2224 2225 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %x / exit do nothing at cycle %d\n",2226 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , hal_time_stamp() );2227 2228 return;2229 }2230 } // end rpc_check()2231 2232 2233 //////////////////////2234 void rpc_thread_func()2235 {2236 // makes the RPC thread not preemptable2237 hal_disable_irq( NULL );2238 2239 thread_t * this = CURRENT_THREAD;2240 remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo;2241 2242 while(1)2243 {2244 // check fifo ownership (ownership should be given by rpc_activate()2245 assert( (this->trdid == rpc_fifo->owner) , __FUNCTION__ ,2246 "thread %x on core[%x,%d] not owner of RPC_FIFO / owner = %x\n",2247 this->trdid, local_cxy, this->core->lid , rpc_fifo->owner );2248 2249 // executes pending RPC(s)2250 rpc_execute_all( rpc_fifo );2251 2252 // release rpc_fifo ownership if required2253 // (this ownership can be lost during RPC execution)2254 if( rpc_fifo->owner == this->trdid ) rpc_fifo->owner = 0;2255 2256 // deschedule or sucide2257 if( LOCAL_CLUSTER->rpc_threads >= CONFIG_RPC_THREADS_MAX ) // suicide2258 {2259 2260 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %x / suicide at cycle %d\n",2261 __FUNCTION__, local_cxy, this->core->lid, this->trdid, hal_time_stamp() );2262 2263 // update core descriptor counter2264 hal_atomic_add( &LOCAL_CLUSTER->rpc_threads , -1 );2265 2266 // suicide2267 thread_exit();2268 }2269 else // deschedule2270 {2271 2272 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %x / deschedule at cycle %d\n",2273 __FUNCTION__, local_cxy, this->core->lid, this->trdid, hal_time_stamp() );2274 2275 sched_yield();2276 2277 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %x / wake up at cycle %d\n",2278 __FUNCTION__, local_cxy, this->core->lid, this->trdid, hal_time_stamp() );2279 2280 }2281 } // end while2282 } // end rpc_thread_func()2283 2284 */2285 2286
Note: See TracChangeset
for help on using the changeset viewer.