Changeset 581 for trunk/kernel/libk
- Timestamp:
- Oct 10, 2018, 3:11:53 PM (6 years ago)
- Location:
- trunk/kernel/libk
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/libk/remote_barrier.c
r563 r581 83 83 84 84 // get pointer on local process descriptor 85 process_t * process = CURRENT_THREAD->process; 85 thread_t * this = CURRENT_THREAD; 86 process_t * process = this->process; 87 88 #if DEBUG_BARRIER 89 uint32_t cycle = (uint32_t)hal_get_cycles(); 90 if( cycle > DEBUG_BARRIER ) 91 printk("\n[DBG] %s : thread %x in process %x enter / count %d / cycle %d\n", 92 __FUNCTION__, this->trdid, process->pid, count, cycle ); 93 #endif 86 94 87 95 // get extended pointer on reference process … … 110 118 111 119 // initialise barrier 112 hal_remote_s32 113 hal_remote_s32 114 hal_remote_s32 120 hal_remote_s32( XPTR( ref_cxy , &barrier_ptr->nb_threads ) , count ); 121 hal_remote_s32( XPTR( ref_cxy , &barrier_ptr->current ) , 0 ); 122 hal_remote_s32( XPTR( ref_cxy , &barrier_ptr->sense ) , 0 ); 115 123 hal_remote_spt( XPTR( ref_cxy , &barrier_ptr->ident ) , (void*)ident ); 116 124 117 xlist_ entry_init( XPTR( ref_cxy , &barrier_ptr->list ) );125 xlist_root_init( XPTR( ref_cxy , &barrier_ptr->root ) ); 118 126 119 127 // register barrier in reference process xlist … … 125 133 remote_busylock_release( XPTR( ref_cxy , &ref_ptr->sync_lock ) ); 126 134 135 #if DEBUG_BARRIER 136 cycle = (uint32_t)hal_get_cycles(); 137 if( cycle > DEBUG_BARRIER ) 138 printk("\n[DBG] %s : thread %x in process %x exit / barrier %x in cluster %x / cycle %d\n", 139 __FUNCTION__, this->trdid, process->pid, barrier_ptr, ref_cxy, cycle ); 140 #endif 141 127 142 return 0; 128 } 143 144 } // end remote_barrier_create() 129 145 130 146 //////////////////////////////////////////////// … … 162 178 rpc_kcm_free_client( barrier_cxy , barrier_ptr , KMEM_BARRIER ); 163 179 } 164 } 180 } // end remote_barrier_destroy() 165 181 166 182 ///////////////////////////////////////////// … … 168 184 { 169 185 uint32_t expected; 186 uint32_t sense; 170 187 uint32_t current; 171 uint32_t count; 172 uint32_t sense; 173 reg_t irq_state; 188 uint32_t nb_threads; 174 189 xptr_t root_xp; 175 176 // get cluster and local pointer on calling thread 177 cxy_t thread_cxy = local_cxy; 178 thread_t * thread_ptr = CURRENT_THREAD; 179 180 // check calling thread can yield 181 assert( (thread_ptr->busylocks == 0), 182 "cannot yield : busylocks = %d\n", thread_ptr->busylocks ); 190 xptr_t lock_xp; 191 xptr_t current_xp; 192 xptr_t sense_xp; 193 xptr_t nb_threads_xp; 194 195 // get pointer on calling thread 196 thread_t * this = CURRENT_THREAD; 197 198 // check calling thread can yield 199 thread_assert_can_yield( this , __FUNCTION__ ); 183 200 184 201 // get cluster and local pointer on remote barrier 185 remote_barrier_t * barrier_ptr = (remote_barrier_t *)GET_PTR( barrier_xp );202 remote_barrier_t * barrier_ptr = GET_PTR( barrier_xp ); 186 203 cxy_t barrier_cxy = GET_CXY( barrier_xp ); 187 204 188 // get count and root fields from barrier descriptor 189 count = hal_remote_l32 ( XPTR( barrier_cxy , &barrier_ptr->nb_threads ) ); 190 root_xp = hal_remote_l64( XPTR( barrier_cxy , &barrier_ptr->root ) ); 191 192 // get barrier sense value 193 sense = hal_remote_l32( XPTR( barrier_cxy , &barrier_ptr->sense ) ); 205 #if DEBUG_BARRIER 206 uint32_t cycle = (uint32_t)hal_get_cycles(); 207 if( cycle > DEBUG_BARRIER ) 208 printk("\n[DBG] %s : thread %x in process %x enter / barrier %x in cluster %x / cycle %d\n", 209 __FUNCTION__, this->trdid, this->process->pid, barrier_ptr, barrier_cxy, cycle ); 210 #endif 211 212 // compute extended pointers on various barrier fields 213 lock_xp = XPTR( barrier_cxy , &barrier_ptr->lock ); 214 root_xp = XPTR( barrier_cxy , &barrier_ptr->root ); 215 current_xp = XPTR( barrier_cxy , &barrier_ptr->current ); 216 sense_xp = XPTR( barrier_cxy , &barrier_ptr->sense ); 217 nb_threads_xp = XPTR( barrier_cxy , &barrier_ptr->nb_threads ); 218 219 // take busylock protecting the remote_barrier 220 remote_busylock_acquire( lock_xp ); 221 222 #if (DEBUG_BARRIER & 1) 223 cycle = (uint32_t)hal_get_cycles(); 224 if( cycle > DEBUG_BARRIER ) 225 printk("\n[DBG] %s : thread %x in process %x get lock / cycle %d\n", 226 __FUNCTION__, this->trdid, this->process->pid, cycle ); 227 #endif 228 229 // get sense and nb_threads values from barrier descriptor 230 sense = hal_remote_l32( sense_xp ); 231 nb_threads = hal_remote_l32( nb_threads_xp ); 194 232 195 233 // compute expected value … … 197 235 else expected = 0; 198 236 199 // atomically increment current 200 current = hal_remote_atomic_add( XPTR( barrier_cxy , &barrier_ptr->current ) , 1 ); 237 #if (DEBUG_BARRIER & 1) 238 cycle = (uint32_t)hal_get_cycles(); 239 if( cycle > DEBUG_BARRIER ) 240 printk("\n[DBG] %s : thread %x in process %x / count %d / sense %d / cycle %d\n", 241 __FUNCTION__, this->trdid, this->process->pid, nb_threads, sense, cycle ); 242 #endif 243 244 // atomically increment current, and get value before increment 245 current = hal_remote_atomic_add( current_xp , 1 ); 201 246 202 247 // last thread reset current, toggle sense, and activate all waiting threads 203 248 // other threads block, register in queue, and deschedule 204 249 205 if( current == ( count-1) ) // last thread206 { 207 hal_remote_s32( XPTR( barrier_cxy , &barrier_ptr->current), 0 );208 hal_remote_s32( XPTR( barrier_cxy , &barrier_ptr->sense ), expected );209 210 // activate waiting threads if required211 if( xlist_is_empty( root_xp ) == false )250 if( current == (nb_threads-1) ) // last thread 251 { 252 hal_remote_s32( current_xp , 0 ); 253 hal_remote_s32( sense_xp , expected ); 254 255 // unblock all waiting threads 256 while( xlist_is_empty( root_xp ) == false ) 212 257 { 213 // disable interrupts 214 hal_disable_irq( &irq_state ); 215 216 xptr_t iter_xp; 217 xptr_t thread_xp; 218 XLIST_FOREACH( root_xp , iter_xp ) 219 { 220 // get extended pointer on waiting thread 221 thread_xp = XLIST_ELEMENT( iter_xp , thread_t , wait_list ); 222 223 // remove waiting thread from queue 224 remote_busylock_acquire( XPTR( barrier_cxy , &barrier_ptr->lock ) ); 225 xlist_unlink( XPTR( barrier_cxy , &barrier_ptr->list ) ); 226 remote_busylock_release( XPTR( barrier_cxy , &barrier_ptr->lock ) ); 227 228 // unblock waiting thread 229 thread_unblock( thread_xp , THREAD_BLOCKED_USERSYNC ); 230 } 231 232 // restore interrupts 233 hal_restore_irq( irq_state ); 258 // get pointers on first waiting thread 259 xptr_t thread_xp = XLIST_FIRST( root_xp , thread_t , wait_list ); 260 cxy_t thread_cxy = GET_CXY( thread_xp ); 261 thread_t * thread_ptr = GET_PTR( thread_xp ); 262 263 #if (DEBUG_BARRIER & 1) 264 cycle = (uint32_t)hal_get_cycles(); 265 if( cycle > DEBUG_BARRIER ) 266 printk("\n[DBG] %s : thread %x in process %x / unblock thread %x / cycle %d\n", 267 __FUNCTION__, this->trdid, this->process->pid, thread_ptr, cycle ); 268 #endif 269 270 // remove waiting thread from queue 271 xlist_unlink( XPTR( thread_cxy , &thread_ptr->wait_list ) ); 272 273 // unblock waiting thread 274 thread_unblock( thread_xp , THREAD_BLOCKED_USERSYNC ); 234 275 } 276 277 // release busylock protecting the remote_barrier 278 remote_busylock_release( lock_xp ); 235 279 } 236 280 else // not the last thread 237 281 { 238 // disable interrupts 239 hal_disable_irq( &irq_state ); 282 283 #if (DEBUG_BARRIER & 1) 284 cycle = (uint32_t)hal_get_cycles(); 285 if( cycle > DEBUG_BARRIER ) 286 printk("\n[DBG] %s : thread %x in process %x / blocked / cycle %d\n", 287 __FUNCTION__, this->trdid, this->process->pid, cycle ); 288 #endif 240 289 241 290 // register calling thread in barrier waiting queue 242 xptr_t entry_xp = XPTR( thread_cxy , &thread_ptr->wait_list ); 243 244 remote_busylock_acquire( XPTR( barrier_cxy , &barrier_ptr->lock ) ); 245 xlist_add_last( root_xp , entry_xp ); 246 remote_busylock_release( XPTR( barrier_cxy , &barrier_ptr->lock ) ); 247 248 // block & deschedule the calling thread 249 thread_block( XPTR( local_cxy , thread_ptr ) , THREAD_BLOCKED_USERSYNC ); 291 xlist_add_last( root_xp , XPTR( local_cxy , &this->wait_list ) ); 292 293 // block calling thread 294 thread_block( XPTR( local_cxy , this ) , THREAD_BLOCKED_USERSYNC ); 295 296 // release busylock protecting the remote_barrier 297 remote_busylock_release( lock_xp ); 298 299 // deschedule 250 300 sched_yield("blocked on barrier"); 251 252 // restore interrupts 253 hal_restore_irq( irq_state ); 254 } 255 } 301 } 302 303 #if DEBUG_BARRIER 304 cycle = (uint32_t)hal_get_cycles(); 305 if( cycle > DEBUG_BARRIER ) 306 printk("\n[DBG] %s : thread %x in process %x exit / barrier %x in cluster %x / cycle %d\n", 307 __FUNCTION__, this->trdid, this->process->pid, barrier_ptr, barrier_cxy, cycle ); 308 #endif 309 310 } // end remote_barrier_wait() -
trunk/kernel/libk/remote_barrier.h
r563 r581 33 33 * This file defines a POSIX compliant barrier. 34 34 * 35 * It is used by multi-threaded iuser applications to synchronise threads running in35 * It is used by multi-threaded user applications to synchronise threads running in 36 36 * different clusters, as all access functions uses hal_remote_l32() / hal_remote_s32() 37 37 * remote access primitives. … … 61 61 typedef struct remote_barrier_s 62 62 { 63 remote_busylock_t lock; /*! lock protecting xlist of arrived threads*/63 remote_busylock_t lock; /*! lock protecting list of waiting threads */ 64 64 intptr_t ident; /*! virtual address in user space == identifier */ 65 65 uint32_t current; /*! number of arrived threads */ … … 67 67 uint32_t nb_threads; /*! number of expected threads */ 68 68 xlist_entry_t list; /*! member of list of barriers in same process */ 69 xlist_entry_t root; /*! root of list of arrivedthreads */69 xlist_entry_t root; /*! root of list of waiting threads */ 70 70 } 71 71 remote_barrier_t; -
trunk/kernel/libk/remote_condvar.c
r563 r581 186 186 thread_t * this = CURRENT_THREAD; 187 187 188 // check calling thread can yield 189 assert( (this->busylocks == 0), 190 "cannot yield : busylocks = %d\n", this->busylocks ); 188 // check calling thread can yield 189 thread_assert_can_yield( this , __FUNCTION__ ); 191 190 192 191 // get condvar cluster and local pointer -
trunk/kernel/libk/remote_condvar.h
r563 r581 31 31 32 32 /******************************************************************************************* 33 * This file define an user level POSIX compliant condition variable.33 * This file defines the ALMOS-MKH implentation of an user level, POSIX compliant condvar. 34 34 * 35 35 * It can be used by muti-threaded user applications to synchronise user threads … … 44 44 * is not running in the reference cluster. 45 45 * 46 * The blocking "remote_condvar_wait() function allow xthe calling thread to efficiently46 * The blocking "remote_condvar_wait() function allows the calling thread to efficiently 47 47 * wait for a change in a shared user object. The calling thread blocks and register in 48 48 * a waiting queue attached to the condvar. The blocked thread is unblocked by another -
trunk/kernel/libk/remote_mutex.c
r563 r581 191 191 void remote_mutex_lock( xptr_t mutex_xp ) 192 192 { 193 // get cluster and pointers on calling thread 194 cxy_t caller_cxy = local_cxy; 195 thread_t * caller_ptr = CURRENT_THREAD; 196 xptr_t caller_xp = XPTR( caller_cxy , caller_ptr ); 197 198 // check calling thread can yield 199 thread_assert_can_yield( caller_ptr , __FUNCTION__ ); 200 193 201 // get cluster and local pointer on mutex 194 202 remote_mutex_t * mutex_ptr = GET_PTR( mutex_xp ); … … 200 208 xptr_t root_xp = XPTR( mutex_cxy , &mutex_ptr->root ); 201 209 xptr_t lock_xp = XPTR( mutex_cxy , &mutex_ptr->lock ); 202 203 // get cluster and pointers on calling thread204 cxy_t caller_cxy = local_cxy;205 thread_t * caller_ptr = CURRENT_THREAD;206 xptr_t caller_xp = XPTR( caller_cxy , caller_ptr );207 208 // check calling thread can yield209 assert( (caller_ptr->busylocks == 0),210 "cannot yield : busylocks = %d\n", caller_ptr->busylocks );211 210 212 211 while( 1 ) -
trunk/kernel/libk/remote_mutex.h
r563 r581 29 29 #include <xlist.h> 30 30 31 /*************************************************************************************** 32 * This file definesan user level POSIX compliant mutex.31 /***************************************************************************************** 32 * This file defines the ALMOS-MKH implementation of an user level POSIX compliant mutex. 33 33 * 34 34 * It can be used by muti-threaded user applications to synchronise user threads … … 49 49 * The "remote_mutex_unlock()" function unblocks the first waiting thread in the queue 50 50 * without releasing the mutex if queue is not empty. 51 ************************************************************************************** /51 ****************************************************************************************/ 52 52 53 53 /***************************************************************************************** … … 57 57 typedef struct remote_mutex_s 58 58 { 59 remote_busylock_t lock; /*! lock protecting the mutex state */60 intptr_t ident; /*! mutex identifier (vaddr in user space) */61 uint32_t taken; /*! mutex non allocated if 0 */62 xlist_entry_t list; /*! member of list of mutex in same process */63 xlist_entry_t root; /*! root of list of waiting threads */64 xptr_t owner; /*! extended pointer on owner thread */59 remote_busylock_t lock; /*! lock protecting the mutex state */ 60 intptr_t ident; /*! mutex identifier (vaddr in user space) */ 61 uint32_t taken; /*! mutex non allocated if 0 */ 62 xlist_entry_t list; /*! member of list of mutex in same process */ 63 xlist_entry_t root; /*! root of list of waiting threads */ 64 xptr_t owner; /*! extended pointer on owner thread */ 65 65 } 66 66 remote_mutex_t; 67 67 68 /*************************************************************************************** 68 /***************************************************************************************** 69 69 * This function returns an extended pointer on the remote mutex, identified 70 70 * by its virtual address in a given user process. It makes an associative search, 71 71 * scanning the list of mutex rooted in the reference process descriptor. 72 *************************************************************************************** 72 ***************************************************************************************** 73 73 * @ ident : mutex virtual address, used as identifier. 74 74 * @ returns extended pointer on mutex if success / returns XPTR_NULL if not found. 75 ************************************************************************************** /75 ****************************************************************************************/ 76 76 xptr_t remote_mutex_from_ident( intptr_t ident ); 77 77 78 /*************************************************************************************** 78 /***************************************************************************************** 79 79 * This function implements the pthread_mutex_init() syscall. 80 80 * It allocates memory for the mutex descriptor in the reference cluster for 81 81 * the calling process, it initializes the mutex state, and register it in the 82 82 * list of mutex owned by the reference process. 83 *************************************************************************************** 83 ***************************************************************************************** 84 84 * @ ident : mutex identifier (virtual address in user space). 85 85 * @ return 0 if success / ENOMEM if no memory / EINVAL if invalid argument. 86 ************************************************************************************** /86 ****************************************************************************************/ 87 87 error_t remote_mutex_create( intptr_t ident ); 88 88 89 /*************************************************************************************** 89 /***************************************************************************************** 90 90 * This function implements the pthread_mutex_destroy() syscall. 91 91 * It releases thr memory allocated for the mutex descriptor, and remove the mutex 92 92 * from the list of mutex owned by the reference process. 93 *************************************************************************************** 93 ***************************************************************************************** 94 94 * @ mutex_xp : extended pointer on mutex descriptor. 95 ************************************************************************************** /95 ****************************************************************************************/ 96 96 void remote_mutex_destroy( xptr_t mutex_xp ); 97 97 98 /*************************************************************************************** 98 /***************************************************************************************** 99 99 * This blocking function implements the pthread_mutex_lock() syscall. 100 100 * It returns only when the ownership of the mutex identified by the <mutex_xp> 101 101 * argument has been obtained by the calling thread. It register in the mutex waiting 102 102 * queue when the mutex is already taken by another thread. 103 *************************************************************************************** 103 ***************************************************************************************** 104 104 * @ mutex_xp : extended pointer on mutex descriptor. 105 ************************************************************************************** /105 ****************************************************************************************/ 106 106 void remote_mutex_lock( xptr_t mutex_xp ); 107 107 108 /*************************************************************************************** 108 /***************************************************************************************** 109 109 * This function implements the pthread_mutex_unlock() syscall. 110 110 * It cheks that the calling thread is actually the mutex owner. … … 112 112 * It unblocks the first thread registered in the mutex waiting queue, when the 113 113 * queue is not empty. 114 *************************************************************************************** 114 ***************************************************************************************** 115 115 * @ mutex_xp : extended pointer on mutex descriptor. 116 116 * @ return 0 if success / return non zero if calling thread is not mutex owner. 117 ************************************************************************************** /117 ****************************************************************************************/ 118 118 error_t remote_mutex_unlock( xptr_t mutex_xp ); 119 119 120 /*************************************************************************************** 120 /***************************************************************************************** 121 121 * This non blocking function function attempts to lock a mutex without blocking. 122 *************************************************************************************** 122 ***************************************************************************************** 123 123 * @ mutex_xp : extended pointer on mutex descriptor. 124 124 * @ return 0 if success / return non zero if already taken. 125 ************************************************************************************** /125 ****************************************************************************************/ 126 126 error_t remote_mutex_trylock( xptr_t mutex_xp ); 127 127 -
trunk/kernel/libk/remote_sem.h
r563 r581 109 109 110 110 /****************************yy*************************************************************** 111 * This function mplements the SEM_POST operation.111 * This function implements the SEM_POST operation. 112 112 * - It atomically increments the remote semaphore. 113 113 * - If the waiting queue is not empty, it wakes up all waiting thread.
Note: See TracChangeset
for help on using the changeset viewer.