Changeset 440 for trunk/kernel/kern/chdev.c
- Timestamp:
- May 3, 2018, 5:51:22 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/kern/chdev.c
r438 r440 124 124 { 125 125 thread_t * server_ptr; // local pointer on server thread associated to chdev 126 xptr_t server_xp; // extended pointer on server thread 126 127 core_t * core_ptr; // local pointer on core running the server thread 127 128 uint32_t lid; // core running the server thread local index … … 140 141 thread_t * this = CURRENT_THREAD; 141 142 142 // get device descriptorcluster and local pointer143 // get chdev cluster and local pointer 143 144 cxy_t chdev_cxy = GET_CXY( chdev_xp ); 144 chdev_t * chdev_ptr = (chdev_t *)GET_PTR( chdev_xp ); 145 chdev_t * chdev_ptr = GET_PTR( chdev_xp ); 146 147 // get local and extended pointers on server thread 148 server_ptr = (thread_t *)hal_remote_lpt( XPTR( chdev_cxy , &chdev_ptr->server) ); 149 server_xp = XPTR( chdev_cxy , server_ptr ); 150 151 // get local pointer on core running the server thread 152 core_ptr = (core_t *)hal_remote_lpt( XPTR( chdev_cxy , &server_ptr->core ) ); 153 154 // get server core local index 155 lid = hal_remote_lw( XPTR( chdev_cxy , &core_ptr->lid ) ); 145 156 146 157 #if (DEBUG_CHDEV_CMD_RX || DEBUG_CHDEV_CMD_TX) … … 162 173 #endif 163 174 164 // build extended pointers on client thread xlist and device root 165 xptr_t list_xp = XPTR( local_cxy , &this->wait_list ); 166 xptr_t root_xp = XPTR( chdev_cxy , &chdev_ptr->wait_root ); 167 168 // get local pointer on server thread 169 server_ptr = (thread_t *)hal_remote_lpt( XPTR( chdev_cxy , &chdev_ptr->server) ); 170 171 // build extended pointer on chdev lock protecting queue 175 // build extended pointer on client thread xlist 176 xptr_t list_xp = XPTR( local_cxy , &this->wait_list ); 177 178 // build extended pointer on chdev waiting queue root 179 xptr_t root_xp = XPTR( chdev_cxy , &chdev_ptr->wait_root ); 180 181 // build extended pointer on server thread blocked state 182 xptr_t blocked_xp = XPTR( chdev_cxy , &server_ptr->blocked ); 183 184 // build extended pointer on lock protecting chdev waiting queue 172 185 lock_xp = XPTR( chdev_cxy , &chdev_ptr->wait_lock ); 173 186 174 // get local pointer on core running the server thread 175 core_ptr = (core_t *)hal_remote_lpt( XPTR( chdev_cxy , &server_ptr->core ) ); 176 177 // get core local index 178 lid = hal_remote_lw( XPTR( chdev_cxy , &core_ptr->lid ) ); 179 180 // compute server core != thread core 181 different = (lid != this->core->lid) || (local_cxy != chdev_cxy); 182 183 // enter critical section to make atomic : 184 // (1) client blocking 185 // (2) client registration in server queue 186 // (3) IPI to force server scheduling 187 // (4) descheduling 187 // critical section for the following sequence: 188 // (1) take the lock protecting waiting queue 189 // (2) block the client thread 190 // (3) unblock the server thread if required 191 // (4) register client thread in server queue 192 // (5) send IPI to force server scheduling 193 // (6) release the lock protecting waiting queue 194 // (7) deschedule 188 195 // ... in this order 196 197 // enter critical section 189 198 hal_disable_irq( &save_sr ); 199 200 // take the lock 201 remote_spinlock_lock( lock_xp ); 190 202 191 203 // block current thread 192 204 thread_block( XPTR( local_cxy , CURRENT_THREAD ) , THREAD_BLOCKED_IO ); 193 205 206 if( hal_remote_lw( blocked_xp ) & THREAD_BLOCKED_IDLE ) 207 thread_unblock( server_xp , THREAD_BLOCKED_IDLE ); 208 194 209 // register client thread in waiting queue 195 remote_spinlock_lock( lock_xp );196 210 xlist_add_last( root_xp , list_xp ); 197 remote_spinlock_unlock( lock_xp ); 198 199 // send IPI to core running the server thread if required211 212 // send IPI to core running the server thread when server != client 213 different = (lid != this->core->lid) || (local_cxy != chdev_cxy); 200 214 if( different ) dev_pic_send_ipi( chdev_cxy , lid ); 201 215 216 // release lock 217 remote_spinlock_unlock( lock_xp ); 218 202 219 // deschedule 203 220 assert( thread_can_yield( this ) , __FUNCTION__ , "illegal sched_yield\n" ); … … 260 277 remote_spinlock_unlock( lock_xp ); 261 278 279 // block 280 thread_block( XPTR( local_cxy , server ) , THREAD_BLOCKED_IDLE ); 281 262 282 // deschedule 283 assert( thread_can_yield( server ) , __FUNCTION__ , "illegal sched_yield\n" ); 263 284 sched_yield("I/O queue empty"); 264 285 } 265 286 else // waiting queue not empty 266 287 { 288 // get extended pointer on first client thread 289 client_xp = XLIST_FIRST_ELEMENT( root_xp , thread_t , wait_list ); 290 291 // get client thread cluster and local pointer 292 client_cxy = GET_CXY( client_xp ); 293 client_ptr = GET_PTR( client_xp ); 294 295 // remove this first client thread from waiting queue 296 xlist_unlink( XPTR( client_cxy , &client_ptr->wait_list ) ); 297 267 298 // release lock 268 299 remote_spinlock_unlock( lock_xp ); 269 270 // get extended pointer on first client thread271 client_xp = XLIST_FIRST_ELEMENT( root_xp , thread_t , wait_list );272 273 // get client thread cluster, local pointer, and identifier274 client_cxy = GET_CXY( client_xp );275 client_ptr = (thread_t *)GET_PTR( client_xp );276 300 277 301 #if DEBUG_CHDEV_SERVER_RX … … 300 324 chdev->cmd( client_xp ); 301 325 302 // remove the client thread from waiting queue303 remote_spinlock_lock( lock_xp );304 xlist_unlink( XPTR( client_cxy , &client_ptr->wait_list ) );305 remote_spinlock_unlock( lock_xp );306 307 326 // unblock client thread 308 327 thread_unblock( client_xp , THREAD_BLOCKED_IO ); … … 343 362 chdev_t * chdev_ptr; 344 363 364 assert( (file_xp != XPTR_NULL) , __FUNCTION__, 365 "file_xp == XPTR_NULL\n" ); 366 345 367 // get cluster and local pointer on remote file descriptor 346 368 // associated inode and chdev are stored in same cluster as the file desc. … … 353 375 354 376 assert( (inode_type == INODE_TYPE_DEV) , __FUNCTION__ , 355 "inode type %d is not INODE_TYPE_DEV ", inode_type );377 "inode type %d is not INODE_TYPE_DEV\n", inode_type ); 356 378 357 379 // get chdev local pointer from inode extension
Note: See TracChangeset
for help on using the changeset viewer.