- Timestamp:
- Oct 10, 2018, 3:11:53 PM (6 years ago)
- Location:
- trunk
- Files:
-
- 21 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/kern/chdev.c
r564 r581 154 154 chdev_t * chdev_ptr = GET_PTR( chdev_xp ); 155 155 156 // check calling thread can yield 157 assert( (this->busylocks == 0), 158 "cannot yield : busylocks = %d\n", this->busylocks ); 156 // check calling thread can yield 157 thread_assert_can_yield( this , __FUNCTION__ ); 159 158 160 159 // get local and extended pointers on server thread … … 197 196 // build extended pointer on lock protecting chdev waiting queue 198 197 lock_xp = XPTR( chdev_cxy , &chdev_ptr->wait_lock ); 198 199 // TODO the hal_disable_irq() / hal_restore_irq() 200 // in the sequence below is probably useless, as it is 201 // already done by the busylock_acquire() / busylock_release() 202 // => remove it [AG] october 2018 199 203 200 204 // critical section for the following sequence: … … 206 210 // (6) release the lock protecting waiting queue 207 211 // (7) deschedule 208 // ... in this order209 212 210 213 // enter critical section -
trunk/kernel/kern/process.c
r580 r581 112 112 cxy_t chdev_cxy; 113 113 pid_t parent_pid; 114 lpid_t process_lpid;115 lpid_t parent_lpid;116 114 117 115 // get parent process cluster and local pointer … … 121 119 // get parent_pid 122 120 parent_pid = hal_remote_l32( XPTR( parent_cxy , &parent_ptr->pid ) ); 123 124 // get process and parent lpid125 process_lpid = LPID_FROM_PID( pid );126 parent_lpid = LPID_FROM_PID( parent_pid );127 121 128 122 #if DEBUG_PROCESS_REFERENCE_INIT … … 156 150 157 151 // define the stdin/stdout/stderr pseudo files <=> select a TXT terminal. 158 if( (process_lpid == 1) || // INIT process 159 (parent_lpid == 1) ) // KSH process 160 { 161 // allocate a TXT channel 162 if( process_lpid == 1 ) txt_id = 0; // INIT 163 else txt_id = process_txt_alloc(); // KSH 152 if( (pid == 1) || (parent_pid == 1) ) // INIT or KSH process 153 { 154 // select a TXT channel 155 if( pid == 1 ) txt_id = 0; // INIT 156 else txt_id = process_txt_alloc(); // KSH 164 157 165 158 // attach process to TXT … … 1791 1784 if( txt_owner_xp == process_xp ) 1792 1785 { 1793 nolock_printk("PID %X | PPID %X | TS %X | %s (FG) |%X | %d | %s\n",1794 pid, ppid, state, txt_name, process_ptr, th_nr, elf_name );1786 nolock_printk("PID %X | %s (FG) | %X | PPID %X | TS %X | %d | %s\n", 1787 pid, txt_name, process_ptr, ppid, state, th_nr, elf_name ); 1795 1788 } 1796 1789 else 1797 1790 { 1798 nolock_printk("PID %X | PPID %X | TS %X | %s (BG) |%X | %d | %s\n",1799 pid, ppid, state, txt_name, process_ptr, th_nr, elf_name );1791 nolock_printk("PID %X | %s (BG) | %X | PPID %X | TS %X | %d | %s\n", 1792 pid, txt_name, process_ptr, ppid, state, th_nr, elf_name ); 1800 1793 } 1801 1794 } // end process_display() … … 1806 1799 //////////////////////////////////////////////////////////////////////////////////////// 1807 1800 1808 //////////////////////////// 1801 ////////////////////////////////// 1809 1802 uint32_t process_txt_alloc( void ) 1810 1803 { -
trunk/kernel/kern/rpc.c
r564 r581 142 142 client_core_lid = this->core->lid; 143 143 144 // check calling thread can yield when it is not the idlethread145 assert( (this->busylocks == 0) || (this->type == THREAD_IDLE), 146 "cannot yield : busylocks = %d\n", this->busylocks);144 // check calling thread can yield when client thread is not the IDLE thread 145 // RPCs executed by the IDLE thread during kernel_init do not deschedule 146 if( this->type != THREAD_IDLE ) thread_assert_can_yield( this , __FUNCTION__ ); 147 147 148 148 #if DEBUG_RPC_CLIENT_GENERIC … … 204 204 205 205 // wait RPC completion before returning if blocking RPC : 206 // - descheduling without blocking if thread idle (in lernel init)206 // - descheduling without blocking if thread idle (in kernel init) 207 207 // - block and deschedule policy for any other thread 208 208 if ( rpc->blocking ) -
trunk/kernel/kern/scheduler.c
r564 r581 411 411 #endif 412 412 413 // check current thread busylocks counter 413 // This assert should never be false, as this check must be 414 // done before by any function that can possibly deschedule... 414 415 assert( (current->busylocks == 0), 415 " thread cannot yield :busylocks = %d\n", current->busylocks );416 "unexpected descheduling of thread holding %d busylocks = %d\n", current->busylocks ); 416 417 417 418 // activate or create an RPC thread if RPC_FIFO non empty -
trunk/kernel/kern/thread.c
r580 r581 190 190 if( error ) 191 191 { 192 printk("\n[ERROR] in %s : cannot get TRDID\n", __FUNCTION__ ); 192 printk("\n[ERROR] in %s : thread %x in process %x cannot get TRDID in cluster %x\n" 193 " for thread %s in process %x / cycle %d\n", 194 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, 195 local_cxy, thread_type_str(type), process->pid, (uint32_t)hal_get_cycles() ); 193 196 return EINVAL; 194 197 } … … 710 713 711 714 assert( ( (type == THREAD_IDLE) || (type == THREAD_RPC) || (type == THREAD_DEV) ) , 712 715 "illegal thread type" ); 713 716 714 717 assert( (core_lid < LOCAL_CLUSTER->cores_nr) , 715 718 "illegal core_lid" ); 716 719 717 720 #if DEBUG_THREAD_KERNEL_CREATE … … 725 728 thread = thread_alloc(); 726 729 727 if( thread == NULL ) return ENOMEM; 730 if( thread == NULL ) 731 { 732 printk("\n[ERROR] in %s : thread %x in process %x\n" 733 " no memory for thread descriptor\n", 734 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid ); 735 return ENOMEM; 736 } 728 737 729 738 // initialize thread descriptor … … 738 747 if( error ) // release allocated memory for thread descriptor 739 748 { 749 printk("\n[ERROR] in %s : thread %x in process %x\n" 750 " cannot initialize thread descriptor\n", 751 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid ); 740 752 thread_release( thread ); 741 753 return ENOMEM; … … 744 756 // allocate & initialize CPU context 745 757 error = hal_cpu_context_alloc( thread ); 758 746 759 if( error ) 747 760 { 761 printk("\n[ERROR] in %s : thread %x in process %x\n" 762 " cannot cannot create CPU context\n", 763 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid ); 748 764 thread_release( thread ); 749 765 return EINVAL; 750 766 } 767 751 768 hal_cpu_context_init( thread ); 752 769 … … 1364 1381 void thread_display_busylocks( xptr_t thread_xp ) 1365 1382 { 1366 if( DEBUG_BUSYLOCK ) 1367 { 1368 xptr_t iter_xp; 1369 1370 // get cluster and local pointer of target thread 1371 cxy_t thread_cxy = GET_CXY( thread_xp ); 1372 thread_t * thread_ptr = GET_PTR( thread_xp ); 1373 1374 // get target thread TRDID and busylocks 1375 trdid_t trdid = hal_remote_l32(XPTR( thread_cxy , &thread_ptr->trdid )); 1376 uint32_t locks = hal_remote_l32(XPTR( thread_cxy , &thread_ptr->busylocks )); 1377 1378 // get target thread process and PID; 1379 process_t * process = hal_remote_lpt(XPTR( thread_cxy , &thread_ptr->process )); 1380 pid_t pid = hal_remote_l32(XPTR( thread_cxy , &process->pid )); 1381 1382 // get extended pointer on root of busylocks 1383 xptr_t root_xp = XPTR( thread_cxy , &thread_ptr->busylocks_root ); 1384 1385 // get pointers on TXT0 chdev 1386 xptr_t txt0_xp = chdev_dir.txt_tx[0]; 1387 cxy_t txt0_cxy = GET_CXY( txt0_xp ); 1388 chdev_t * txt0_ptr = GET_PTR( txt0_xp ); 1389 1390 // get extended pointer on remote TXT0 lock 1391 xptr_t txt0_lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock ); 1392 1393 // get TXT0 lock 1394 remote_busylock_acquire( txt0_lock_xp ); 1395 1396 // display header 1397 nolock_printk("\n***** thread %x in process %x : %d busylocks at cycle %d\n", 1398 trdid, pid, locks, (uint32_t)hal_get_cycles() ); 1399 1400 // scan the xlist of busylocks when required 1401 if( locks ) 1383 // get cluster and local pointer of target thread 1384 cxy_t thread_cxy = GET_CXY( thread_xp ); 1385 thread_t * thread_ptr = GET_PTR( thread_xp ); 1386 1387 #if( DEBUG_BUSYLOCK ) 1388 1389 xptr_t iter_xp; 1390 1391 // get target thread TRDID and busylocks 1392 trdid_t trdid = hal_remote_l32(XPTR( thread_cxy , &thread_ptr->trdid )); 1393 uint32_t locks = hal_remote_l32(XPTR( thread_cxy , &thread_ptr->busylocks )); 1394 1395 // get target thread process and PID; 1396 process_t * process = hal_remote_lpt(XPTR( thread_cxy , &thread_ptr->process )); 1397 pid_t pid = hal_remote_l32(XPTR( thread_cxy , &process->pid )); 1398 1399 // get extended pointer on root of busylocks 1400 xptr_t root_xp = XPTR( thread_cxy , &thread_ptr->busylocks_root ); 1401 1402 // get pointers on TXT0 chdev 1403 xptr_t txt0_xp = chdev_dir.txt_tx[0]; 1404 cxy_t txt0_cxy = GET_CXY( txt0_xp ); 1405 chdev_t * txt0_ptr = GET_PTR( txt0_xp ); 1406 1407 // get extended pointer on remote TXT0 lock 1408 xptr_t txt0_lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock ); 1409 1410 // get TXT0 lock 1411 remote_busylock_acquire( txt0_lock_xp ); 1412 1413 // display header 1414 nolock_printk("\n***** thread %x in process %x : %d busylocks at cycle %d\n", 1415 trdid, pid, locks, (uint32_t)hal_get_cycles() ); 1416 1417 // scan the xlist of busylocks when required 1418 if( locks ) 1419 { 1420 XLIST_FOREACH( root_xp , iter_xp ) 1402 1421 { 1403 XLIST_FOREACH( root_xp , iter_xp ) 1404 { 1405 xptr_t lock_xp = XLIST_ELEMENT( iter_xp , busylock_t , xlist ); 1406 cxy_t lock_cxy = GET_CXY( lock_xp ); 1407 busylock_t * lock_ptr = GET_PTR( lock_xp ); 1408 uint32_t lock_type = hal_remote_l32(XPTR( lock_cxy , &lock_ptr->type )); 1409 nolock_printk(" - %s in cluster %x\n", lock_type_str[lock_type] , lock_cxy ); 1410 } 1422 xptr_t lock_xp = XLIST_ELEMENT( iter_xp , busylock_t , xlist ); 1423 cxy_t lock_cxy = GET_CXY( lock_xp ); 1424 busylock_t * lock_ptr = GET_PTR( lock_xp ); 1425 uint32_t lock_type = hal_remote_l32(XPTR( lock_cxy , &lock_ptr->type )); 1426 nolock_printk(" - %s in cluster %x\n", lock_type_str[lock_type] , lock_cxy ); 1411 1427 } 1412 1413 // release TXT0 lock 1414 remote_busylock_release( txt0_lock_xp ); 1415 } 1416 else 1417 { 1418 // display a warning 1419 printk("\n[WARNING] set the DEBUG_BUSYLOCK parmeter in kernel_config.h" 1420 " to use the %s function\n", __FUNCTION__ ); 1421 } 1428 } 1429 1430 // release TXT0 lock 1431 remote_busylock_release( txt0_lock_xp ); 1432 1433 return; 1434 1435 #endif 1436 1437 // display a warning 1438 printk("\n[WARNING] set the DEBUG_BUSYLOCK parmeter in kernel_config.h" 1439 " to display busylocks for thread %x/%x\n", thread_cxy, thread_ptr ); 1440 1422 1441 } // end thread_display_busylock() 1442 -
trunk/kernel/kernel_config.h
r580 r581 27 27 #define _KERNEL_CONFIG_H_ 28 28 29 #define CONFIG_ALMOS_VERSION "Version 1. 0 / August2018"29 #define CONFIG_ALMOS_VERSION "Version 1.1 / October 2018" 30 30 31 31 //////////////////////////////////////////////////////////////////////////////////////////// … … 36 36 //////////////////////////////////////////////////////////////////////////////////////////// 37 37 38 #define DEBUG_BARRIER 0 39 38 40 #define DEBUG_BUSYLOCK 1 39 #define DEBUG_BUSYLOCK_THREAD_XP 0x BC000ULL // selected thread_xp41 #define DEBUG_BUSYLOCK_THREAD_XP 0x11000CC000ULL // selected thread extended pointer (ULL) 40 42 41 43 #define DEBUG_CHDEV_CMD_RX 0 … … 132 134 133 135 #define DEBUG_SCHED_HANDLE_SIGNALS 0 134 #define DEBUG_SCHED_YIELD 1// must be activated by the trace() syscall136 #define DEBUG_SCHED_YIELD 2 // must be activated by the trace() syscall 135 137 #define DEBUG_SCHED_RPC_CHECK 0 136 138 … … 139 141 #define DEBUG_SYSCALLS_ERROR 2 140 142 143 #define DEBUG_SYS_BARRIER 0 141 144 #define DEBUG_SYS_CLOSE 0 142 145 #define DEBUG_SYS_CONDVAR 0 … … 175 178 #define DEBUG_THREAD_DELETE 0 176 179 #define DEBUG_THREAD_DESTROY 0 177 #define DEBUG_THREAD_GET_XPTR 1180 #define DEBUG_THREAD_GET_XPTR 0 178 181 #define DEBUG_THREAD_IDLE 0 179 182 #define DEBUG_THREAD_INIT 0 -
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. -
trunk/kernel/mm/mapper.c
r567 r581 154 154 thread_t * this = CURRENT_THREAD; 155 155 156 // check thread can yield 157 thread_assert_can_yield( this , __FUNCTION__ ); 158 156 159 // take mapper lock in READ_MODE 157 160 rwlock_rd_acquire( &mapper->lock ); -
trunk/kernel/syscalls/shared_include/shared_pthread.h
r566 r581 32 32 33 33 /******************************************************************************************* 34 * These typedef define the POSIX thread related types.34 * These typedef and enum define the shared information related to the POSIX thread. 35 35 ******************************************************************************************/ 36 36 37 typedef unsigned int pthread_mutex_t; 38 typedef unsigned int pthread_mutexattr_t; // TODO not implemented 39 40 typedef unsigned int pthread_cond_t; 41 typedef unsigned int pthread_condattr_t; // TODO not implemented 42 43 typedef unsigned int pthread_rwlock_t; // TODO not implemented 44 typedef unsigned int pthread_rwlockattr_t; // TODO not implemented 45 46 /******************************************************************************************* 47 * This structure and enum define the attributes for the pthread_create() syscall. 48 ******************************************************************************************/ 49 50 typedef unsigned int pthread_t; 37 typedef unsigned int pthread_t; 51 38 52 39 typedef struct pthread_attr_s 53 40 { 54 unsigned int attributes; /*! user defined attributes bit vector*/55 unsigned int cxy; /*! target cluster identifier*/56 unsigned int lid; /*! target core local index*/41 unsigned int attributes; /*! user defined attributes bit vector */ 42 unsigned int cxy; /*! target cluster identifier */ 43 unsigned int lid; /*! target core local index */ 57 44 } 58 45 pthread_attr_t; … … 60 47 enum 61 48 { 62 PT_ATTR_DETACH = 0x0001, /*! user defined not joinable*/63 PT_ATTR_CLUSTER_DEFINED = 0x0002, /*! user defined target cluster*/64 PT_ATTR_CORE_DEFINED = 0x0004, /*! user defined core index in cluster*/49 PT_ATTR_DETACH = 0x0001, /*! user defined not joinable */ 50 PT_ATTR_CLUSTER_DEFINED = 0x0002, /*! user defined target cluster */ 51 PT_ATTR_CORE_DEFINED = 0x0004, /*! user defined core index in cluster */ 65 52 }; 66 53 67 /******************************************************************************************* 68 * Th is enum defines the operation mnemonics for operations on POSIX condition variables.54 /******************************************************************************************* 55 * These typedef and enum define the shared informations related to the POSIX mutex. 69 56 ******************************************************************************************/ 57 58 typedef unsigned int pthread_mutex_t; 59 60 typedef unsigned int pthread_mutexattr_t; // TODO not implemented 61 62 typedef enum 63 { 64 MUTEX_INIT, 65 MUTEX_DESTROY, 66 MUTEX_LOCK, 67 MUTEX_UNLOCK, 68 MUTEX_TRYLOCK, 69 } 70 mutex_operation_t; 71 72 /******************************************************************************************* 73 * These typedef and enum define the shared informations related to the POSIX condvar. 74 ******************************************************************************************/ 75 76 typedef unsigned int pthread_cond_t; 77 78 typedef unsigned int pthread_condattr_t; // TODO not implemented 70 79 71 80 typedef enum … … 79 88 condvar_operation_t; 80 89 90 /******************************************************************************************* 91 * These typedef define and enum the shared informations related to the POSIX rwlock. 92 ******************************************************************************************/ 93 94 typedef unsigned int pthread_rwlock_t; // TODO not implemented 95 96 typedef unsigned int pthread_rwlockattr_t; // TODO not implemented 97 81 98 /******************************************************************************************* 82 * Th is enum defines the operation mnemonics for operations onPOSIX barriers.99 * These typedef and enum define the shared informations related to POSIX barriers. 83 100 ******************************************************************************************/ 101 102 typedef unsigned int pthread_barrier_t; 103 104 typedef struct pthread_barrierattr_s 105 { 106 unsigned int x_size; /*! number of clusters in a row */ 107 unsigned int y_size; /*! number of clusters in a column */ 108 unsigned int nthreads; /*! number of expected threads in a cluster */ 109 } 110 pthread_barrierattr_t; 84 111 85 112 typedef enum … … 91 118 barrier_operation_t; 92 119 93 /******************************************************************************************* 94 * This enum defines the operation mnemonics for operations on POSIX mutex. 95 ******************************************************************************************/ 120 /********************************************************************************************* 121 * These structures define another implementation for the POSIX barrier: 122 * It is implemented as a hierarchical, physically distributed quad-tree, 123 * covering all clusters specified, with the following constraints: 124 * . The involved clusters form a mesh [x_size * y_size] 125 * . The lower left involved cluster is cluster(0,0) 126 * . The number of threads per cluster is the same in all clusters. 127 * 128 * Implementation note: 129 * - The quad three is implemented as a three dimensions array of node[x][y][l] 130 * . [x][y] are the cluster coordinates / max values are (QDT_XMAX-1), (QDT_YMAX-1) 131 * . [l] is the node level / 0 for terminal nodes / (QDT_LMAX-1) for the root node 132 ********************************************************************************************/ 96 133 97 typedef enum 134 /* 135 136 #define QDT_XMAX 16 // max number of clusters in a row 137 #define QDT_YMAX 16 // max number of clusters in a column 138 #define QDT_LMAX 5 // max depth of the quad tree 139 #define QDT_YWIDTH 4 // Y field in cxy, for cxy <=> (x,y) translation 140 #define QDT_YMASK 0xF // Y field in cxy, for cxy <=> (x,y) translation 141 142 typedef struct sqt_node_s 98 143 { 99 MUTEX_INIT, 100 MUTEX_DESTROY, 101 MUTEX_LOCK, 102 MUTEX_UNLOCK, 103 MUTEX_TRYLOCK, 104 } 105 mutex_operation_t; 144 volatile unsigned int sense; // barrier state (toggle) 145 volatile unsigned int count; // number of not arrived tasks 146 unsigned int arity; // number of locally expected tasks 147 unsigned int level; // hierarchical level (0 is bottom) 148 struct sqt_node_s * parent; // pointer on parent node (NULL for root) 149 struct sqt_node_s * child[4]; // pointer on children node (NULL for bottom) 150 } 151 sqt_node_t; 106 152 153 typedef struct pthread_barrier_s 154 { 155 sqt_node_t * node[QDT_XMAX][QDT_YMAX][QDT_LMAX]; 156 } 157 pthread_barrier_t; 107 158 159 */ 108 160 109 161 #endif // _PTHREAD_H_ -
trunk/kernel/syscalls/sys_barrier.c
r508 r581 31 31 #include <remote_barrier.h> 32 32 33 #if DEBUG_SYS_BARRIER 34 ////////////////////////////////////////////////////// 35 static char * sys_barrier_op_str( uint32_t operation ) 36 { 37 if ( operation == BARRIER_INIT ) return "INIT"; 38 else if( operation == BARRIER_DESTROY ) return "DESTROY"; 39 else if( operation == BARRIER_WAIT ) return "WAIT"; 40 else return "undefined"; 41 } 42 #endif 43 33 44 ////////////////////////////////// 34 45 int sys_barrier( void * vaddr, … … 41 52 thread_t * this = CURRENT_THREAD; 42 53 process_t * process = this->process; 54 55 #if DEBUG_SYS_BARRIER 56 uint64_t tm_start; 57 uint64_t tm_end; 58 tm_start = hal_get_cycles(); 59 if( DEBUG_SYS_BARRIER < tm_start ) 60 printk("\n[DBG] %s : thread %x in process %x enter for %s / count %d / cycle %d\n", 61 __FUNCTION__, this->trdid, process->pid, sys_barrier_op_str(operation), count, 62 (uint32_t)tm_start ); 63 #endif 43 64 44 65 // check vaddr in user vspace … … 125 146 } // end switch 126 147 148 #if DEBUG_SYS_BARRIER 149 tm_end = hal_get_cycles(); 150 if( DEBUG_SYS_BARRIER < tm_end ) 151 printk("\n[DBG] %s : thread %x in process %x exit for %s / cost %d / cycle %d\n", 152 __FUNCTION__, this->trdid, process->pid, sys_barrier_op_str(operation), 153 (uint32_t)(tm_end - tm_start), (uint32_t)tm_end ); 154 #endif 155 127 156 return 0; 128 157 -
trunk/libs/libpthread/pthread.c
r573 r581 31 31 #include <syscalls_numbers.h> 32 32 33 #define PTHREAD_BARRIER_DEBUG 034 33 35 34 //////////////////////////////////////////////////////////////////////////////////////////// … … 73 72 } 74 73 75 /////////////////// 74 ///////////////////////// 76 75 int pthread_yield( void ) 77 76 { … … 80 79 81 80 //////////////////////////////////////////////////////////////////////////////////////////// 81 // Mutexes 82 //////////////////////////////////////////////////////////////////////////////////////////// 83 84 ////////////////////////////////////////////////////////// 85 int pthread_mutex_init( pthread_mutex_t * mutex, 86 const pthread_mutexattr_t * attr ) 87 { 88 if( attr != NULL ) 89 { 90 printf("\n[ERROR] in %s : <attr> argument not supported\n", __FUNCTION__); 91 return -1; 92 } 93 94 return hal_user_syscall( SYS_MUTEX, 95 (reg_t)mutex, 96 MUTEX_INIT, 97 0, 0 ); 98 } 99 100 //////////////////////////////////////////////////// 101 int pthread_mutex_destroy( pthread_mutex_t * mutex ) 102 { 103 return hal_user_syscall( SYS_MUTEX, 104 (reg_t)mutex, 105 MUTEX_DESTROY, 106 0, 0 ); 107 } 108 109 ///////////////////////////////////////////////// 110 int pthread_mutex_lock( pthread_mutex_t * mutex ) 111 { 112 return hal_user_syscall( SYS_MUTEX, 113 (reg_t)mutex, 114 MUTEX_LOCK, 115 0, 0 ); 116 } 117 118 //////////////////////////////////////////////////// 119 int pthread_mutex_trylock( pthread_mutex_t * mutex ) 120 { 121 return hal_user_syscall( SYS_MUTEX, 122 (reg_t)mutex, 123 MUTEX_TRYLOCK, 124 0, 0 ); 125 } 126 127 /////////////////////////////////////////////////// 128 int pthread_mutex_unlock( pthread_mutex_t * mutex ) 129 { 130 return hal_user_syscall( SYS_MUTEX, 131 (reg_t)mutex, 132 MUTEX_UNLOCK, 133 0, 0 ); 134 } 135 136 //////////////////////////////////////////////////////////////////////////////////////////// 137 // Condvars 138 //////////////////////////////////////////////////////////////////////////////////////////// 139 140 /////////////////////////////////////////////// 141 int pthread_cond_init( pthread_cond_t * cond, 142 pthread_condattr_t * attr ) 143 { 144 if( attr ) 145 { 146 printf("[ERROR] in %s ; <attr> argument must be NULL\n", __FUNCTION__ ); 147 return -1; 148 } 149 150 return hal_user_syscall( SYS_CONDVAR, 151 (reg_t)cond, 152 CONDVAR_INIT, 153 0, 0 ); 154 } 155 156 ///////////////////////////////////////////////// 157 int pthread_cond_destroy( pthread_cond_t * cond ) 158 { 159 return hal_user_syscall( SYS_CONDVAR, 160 (reg_t)cond, 161 CONDVAR_DESTROY, 162 0, 0 ); 163 } 164 165 ////////////////////////////////////////////// 166 int pthread_cond_wait( pthread_cond_t * cond, 167 pthread_mutex_t * mutex ) 168 { 169 return hal_user_syscall( SYS_CONDVAR, 170 (reg_t)cond, 171 CONDVAR_WAIT, 172 (reg_t)mutex, 173 0 ); 174 } 175 176 //////////////////////////////////////////////// 177 int pthread_cond_signal( pthread_cond_t * cond ) 178 { 179 return hal_user_syscall( SYS_CONDVAR, 180 (reg_t)cond, 181 CONDVAR_SIGNAL, 182 0, 0 ); 183 } 184 185 /////////////////////////////////////////////////// 186 int pthread_cond_broadcast( pthread_cond_t * cond ) 187 { 188 return hal_user_syscall( SYS_CONDVAR, 189 (reg_t)cond, 190 CONDVAR_BROADCAST, 191 0, 0 ); 192 } 193 194 195 //////////////////////////////////////////////////////////////////////////////////////////// 82 196 // Barriers 83 197 //////////////////////////////////////////////////////////////////////////////////////////// 198 199 //////////////////////////////////////////////////////////////// 200 int pthread_barrier_init( pthread_barrier_t * barrier, 201 const pthread_barrierattr_t * attr, 202 unsigned int count ) 203 { 204 return hal_user_syscall( SYS_BARRIER, 205 (reg_t)barrier, 206 BARRIER_INIT, 207 (reg_t)count, 208 0 ); 209 } 210 211 ////////////////////////////////////////////////////////// 212 int pthread_barrier_destroy( pthread_barrier_t * barrier ) 213 { 214 return hal_user_syscall( SYS_BARRIER, 215 (reg_t)barrier, 216 BARRIER_DESTROY, 217 0, 0 ); 218 } 219 220 /////////////////////////////////////////////////////// 221 int pthread_barrier_wait( pthread_barrier_t * barrier ) 222 { 223 return hal_user_syscall( SYS_BARRIER, 224 (reg_t)barrier, 225 BARRIER_WAIT, 226 0, 0 ); 227 } 228 229 /* 230 231 //////////////////////////////////////////////////////////////////////////////////////////// 232 // The following functions define another implementation for the POSX barrier 233 // based on a distributed quadtree implemented in user space, and relying 234 // on a busy waiting policy. 235 //////////////////////////////////////////////////////////////////////////////////////////// 236 84 237 85 238 //////////////////////////////////////////////////////////////////////////////////////////// … … 359 512 } // end pthread_barrier_wait() 360 513 361 //////////////////////////////////////////////////////////////////////////////////////////// 362 // Mutexes 363 //////////////////////////////////////////////////////////////////////////////////////////// 364 365 ////////////////////////////////////////////////////////// 366 int pthread_mutex_init( pthread_mutex_t * mutex, 367 const pthread_mutexattr_t * attr ) 368 { 369 if( attr != NULL ) 370 { 371 printf("\n[ERROR] in %s : <attr> argument not supported\n", __FUNCTION__); 372 return -1; 373 } 374 375 return hal_user_syscall( SYS_MUTEX, 376 (reg_t)mutex, 377 MUTEX_INIT, 378 0, 0 ); 379 } 380 381 //////////////////////////////////////////////////// 382 int pthread_mutex_destroy( pthread_mutex_t * mutex ) 383 { 384 return hal_user_syscall( SYS_MUTEX, 385 (reg_t)mutex, 386 MUTEX_DESTROY, 387 0, 0 ); 388 } 389 390 ///////////////////////////////////////////////// 391 int pthread_mutex_lock( pthread_mutex_t * mutex ) 392 { 393 return hal_user_syscall( SYS_MUTEX, 394 (reg_t)mutex, 395 MUTEX_LOCK, 396 0, 0 ); 397 } 398 399 //////////////////////////////////////////////////// 400 int pthread_mutex_trylock( pthread_mutex_t * mutex ) 401 { 402 return hal_user_syscall( SYS_MUTEX, 403 (reg_t)mutex, 404 MUTEX_TRYLOCK, 405 0, 0 ); 406 } 407 408 /////////////////////////////////////////////////// 409 int pthread_mutex_unlock( pthread_mutex_t * mutex ) 410 { 411 return hal_user_syscall( SYS_MUTEX, 412 (reg_t)mutex, 413 MUTEX_UNLOCK, 414 0, 0 ); 415 } 416 417 //////////////////////////////////////////////////////////////////////////////////////////// 418 // Condition variable 419 //////////////////////////////////////////////////////////////////////////////////////////// 420 421 /////////////////////////////////////////////// 422 int pthread_cond_init( pthread_cond_t * cond, 423 pthread_condattr_t * attr ) 424 { 425 if( attr ) 426 { 427 printf("[ERROR] in %s ; <attr> argument must be NULL\n", __FUNCTION__ ); 428 return -1; 429 } 430 431 return hal_user_syscall( SYS_CONDVAR, 432 (reg_t)cond, 433 CONDVAR_INIT, 434 0, 0 ); 435 } 436 437 ///////////////////////////////////////////////// 438 int pthread_cond_destroy( pthread_cond_t * cond ) 439 { 440 return hal_user_syscall( SYS_CONDVAR, 441 (reg_t)cond, 442 CONDVAR_DESTROY, 443 0, 0 ); 444 } 445 446 ////////////////////////////////////////////// 447 int pthread_cond_wait( pthread_cond_t * cond, 448 pthread_mutex_t * mutex ) 449 { 450 return hal_user_syscall( SYS_CONDVAR, 451 (reg_t)cond, 452 CONDVAR_WAIT, 453 (reg_t)mutex, 454 0 ); 455 } 456 457 //////////////////////////////////////////////// 458 int pthread_cond_signal( pthread_cond_t * cond ) 459 { 460 return hal_user_syscall( SYS_CONDVAR, 461 (reg_t)cond, 462 CONDVAR_SIGNAL, 463 0, 0 ); 464 } 465 466 /////////////////////////////////////////////////// 467 int pthread_cond_broadcast( pthread_cond_t * cond ) 468 { 469 return hal_user_syscall( SYS_CONDVAR, 470 (reg_t)cond, 471 CONDVAR_BROADCAST, 472 0, 0 ); 473 } 474 475 476 514 */ 477 515 478 516 -
trunk/libs/libpthread/pthread.h
r573 r581 25 25 #define _PTHREAD_H_ 26 26 27 #include <shared_pthread.h> 28 27 29 ////////////////////////////////////////////////////////////////////////////////////////////// 28 30 // POSIX thread related functions 29 // 30 // This include the thread creation/destruction, as well as the synchronisations: 31 // barriers, mutexes, and condition variables. 32 ////////////////////////////////////////////////////////////////////////////////////////////// 33 34 #include <shared_pthread.h> 31 ////////////////////////////////////////////////////////////////////////////////////////////// 35 32 36 33 /********************************************************************************************* … … 90 87 91 88 ////////////////////////////////////////////////////////////////////////////////////////////// 92 // POSIX barrier related functions 93 // 94 // These functions are implemented in user space. Only the pthread_barrier_init() function 95 // uses system calls to build the distributed quad-tree infrastructure. 96 ////////////////////////////////////////////////////////////////////////////////////////////// 97 98 /********************************************************************************************* 99 * These structures defines a hierarchical, POSIX compliant, barrier. 100 * - If the barrier attribute in the pthread_barrier_init() is NULL, it is implemented 101 * as a simple, sense reversing barrier, localised in the calling thread cluster. 102 * - If the barrier attribute is defined, it is implemented as a hierarchical, physically 103 * distributed quad-tree, covering all clusters specified, with the following constraints: 104 * . The involved clusters form a mesh [x_size * y_size] 105 * . The lower left involved cluster is cluster(0,0) 106 * . The number of threads per cluster is the same in all clusters. 107 * 108 * Implementation note: 109 * - The quad three is implemented as a three dimensions array of node[x][y][l] 110 * . [x][y] are the cluster coordinates / max values are (QDT_XMAX-1), (QDT_YMAX-1) 111 * . [l] is the node level / 0 for terminal nodes / (QDT_LMAX-1) for the root node 112 ********************************************************************************************/ 113 114 #define QDT_XMAX 16 /*! max number of clusters in a row */ 115 #define QDT_YMAX 16 /*! max number of clusters in a column */ 116 #define QDT_LMAX 5 /*! max depth of the quad tree */ 117 #define QDT_YWIDTH 4 /*! Y field in cxy, for cxy <=> (x,y) translation */ 118 #define QDT_YMASK 0xF /*! Y field in cxy, for cxy <=> (x,y) translation */ 119 120 typedef struct sqt_node_s 121 { 122 volatile unsigned int sense; /*! barrier state (toggle) */ 123 volatile unsigned int count; /*! number of not arrived tasks */ 124 unsigned int arity; /*! number of locally expected tasks */ 125 unsigned int level; /*! hierarchical level (0 is bottom) */ 126 struct sqt_node_s * parent; /*! pointer on parent node (NULL for root) */ 127 struct sqt_node_s * child[4]; /*! pointer on children node (NULL for bottom) */ 128 } 129 sqt_node_t; 130 131 typedef struct pthread_barrier_s 132 { 133 sqt_node_t * node[QDT_XMAX][QDT_YMAX][QDT_LMAX]; 134 } 135 pthread_barrier_t; 136 137 typedef struct pthread_barrierattr_s 138 { 139 unsigned int x_size; /*! number of clusters in a row (0 to x_size-1) */ 140 unsigned int y_size; /*! number of clusters in a column (0 to y_size-1) */ 141 unsigned int nthreads; /*! number of expected threads in a cluster */ 142 } 143 pthread_barrierattr_t; 89 // POSIX mutex related functions 90 ////////////////////////////////////////////////////////////////////////////////////////////// 91 92 /********************************************************************************************* 93 * This function initialise the mutex identified by the <mutex> argument. 94 * The <attr> argument is not supported yet, and must be NULL. 95 ********************************************************************************************* 96 * @ mutex : pointer on mutex in user space. 97 * @ attr : pointer on attributes structure / must be NULL. 98 * @ return 0 if success / return -1 if failure. 99 ********************************************************************************************/ 100 int pthread_mutex_init( pthread_mutex_t * mutex, 101 const pthread_mutexattr_t * attr ); 102 103 /********************************************************************************************* 104 * This function destroy the mutex identified by the <mutex> argument. 105 ********************************************************************************************* 106 * @ mutex : pointer on mutex in user space. 107 * @ return 0 if success / return -1 if failure. 108 ********************************************************************************************/ 109 int pthread_mutex_destroy( pthread_mutex_t * mutex ); 110 111 /********************************************************************************************* 112 * This bloking function locks the mutex identified by the <mutex> argument, 113 * and blocks until it becomes available. 114 ********************************************************************************************* 115 * @ mutex : pointer on mutex in user space. 116 * @ return 0 if success / return -1 if failure. 117 ********************************************************************************************/ 118 int pthread_mutex_lock( pthread_mutex_t * mutex ); 119 120 /********************************************************************************************* 121 * This function unlocks the mutex identified by the <mutex> argument. 122 ********************************************************************************************* 123 * @ mutex : pointer on mutex in user space. 124 * @ return 0 if success / return -1 if failure. 125 ********************************************************************************************/ 126 int pthread_mutex_unlock( pthread_mutex_t * mutex ); 127 128 /********************************************************************************************* 129 * This function tries to lock the mutex identified by the <mutex> argument, 130 * but don't block if the mutex is locked by another thread, including the current thread. 131 ********************************************************************************************* 132 * @ mutex : pointer on mutex in user space. 133 * @ return 0 if success / return -1 if mutex already taken. 134 ********************************************************************************************/ 135 int pthread_mutex_trylock( pthread_mutex_t * mutex ); 136 137 138 ////////////////////////////////////////////////////////////////////////////////////////////// 139 // POSIX condvar related functions 140 ////////////////////////////////////////////////////////////////////////////////////////////// 141 142 /********************************************************************************************* 143 * This function initializes a condition variable identified by the <cond> argument. 144 * WARNING: the <attr> argument is not supported and must be NULL. 145 ********************************************************************************************* 146 * @ cond : [in] pointer on condition in user space. 147 * @ attr : [in] pointer on condition attribute (must be NULL). 148 * @ return 0 if success / return -1 if failure. 149 ********************************************************************************************/ 150 int pthread_cond_init( pthread_cond_t * cond, 151 pthread_condattr_t * attr ); 152 153 /********************************************************************************************* 154 * This function atomically unlocks the <mutex> and blocks the calling thread on the 155 * condition specified by the <cond> argument. The thread unblocks only after another 156 * thread calls the pthread_cond_signal() or pthread_cond_broadcast() functions with the 157 * same condition variable. The mutex must be locked before calling this function, 158 * otherwise the behavior is undefined. Before the pthread_cond_wait() function returns 159 * to the calling function, it re-acquires the <mutex>. 160 ********************************************************************************************* 161 * @ cond : pointer on condition in user space. 162 * @ mutex : pointer on mutex in user space. 163 * @ return 0 if success / return -1 if failure. 164 ********************************************************************************************/ 165 int pthread_cond_wait( pthread_cond_t * cond, 166 pthread_mutex_t * mutex ); 167 168 /********************************************************************************************* 169 * This function unblocks one thread blocked on condition specified by the <cond> argument. 170 ********************************************************************************************* 171 * @ cond : pointer on condition in user space. 172 * @ return 0 if success / return -1 if failure. 173 ********************************************************************************************/ 174 int pthread_cond_signal( pthread_cond_t * cond ); 175 176 /********************************************************************************************* 177 * This function unblocks all threads blocked on condition specified by the <cond> argument. 178 ********************************************************************************************* 179 * @ cond : pointer on condition in user space. 180 * @ return 0 if success / return -1 if failure. 181 ********************************************************************************************/ 182 int pthread_cond_broadcast( pthread_cond_t * cond ); 183 184 /********************************************************************************************* 185 * This function delete the condition variable specified by the <cond> argument. 186 ********************************************************************************************* 187 * @ cond : pointer on condition in user space. 188 * @ return 0 if success / return -1 if failure. 189 ********************************************************************************************/ 190 int pthread_cond_destroy( pthread_cond_t * cond ); 191 192 193 ////////////////////////////////////////////////////////////////////////////////////////////// 194 // POSIX barrier related functions 195 ////////////////////////////////////////////////////////////////////////////////////////////// 144 196 145 197 /********************************************************************************************* … … 186 238 187 239 188 //////////////////////////////////////////////////////////////////////////////////////////////189 // POSIX mutex related functions190 //////////////////////////////////////////////////////////////////////////////////////////////191 192 /*********************************************************************************************193 * This function initialise the mutex identified by the <mutex> argument.194 * The <attr> argument is not supported yet, and must be NULL.195 *********************************************************************************************196 * @ mutex : pointer on mutex in user space.197 * @ attr : pointer on attributes structure / must be NULL.198 * @ return 0 if success / return -1 if failure.199 ********************************************************************************************/200 int pthread_mutex_init( pthread_mutex_t * mutex,201 const pthread_mutexattr_t * attr );202 203 /*********************************************************************************************204 * This function destroy the mutex identified by the <mutex> argument.205 *********************************************************************************************206 * @ mutex : pointer on mutex in user space.207 * @ return 0 if success / return -1 if failure.208 ********************************************************************************************/209 int pthread_mutex_destroy( pthread_mutex_t * mutex );210 211 /*********************************************************************************************212 * This bloking function locks the mutex identified by the <mutex> argument,213 * and blocks until it becomes available.214 *********************************************************************************************215 * @ mutex : pointer on mutex in user space.216 * @ return 0 if success / return -1 if failure.217 ********************************************************************************************/218 int pthread_mutex_lock( pthread_mutex_t * mutex );219 220 /*********************************************************************************************221 * This function unlocks the mutex identified by the <mutex> argument.222 *********************************************************************************************223 * @ mutex : pointer on mutex in user space.224 * @ return 0 if success / return -1 if failure.225 ********************************************************************************************/226 int pthread_mutex_unlock( pthread_mutex_t * mutex );227 228 /*********************************************************************************************229 * This function tries to lock the mutex identified by the <mutex> argument,230 * but don't block if the mutex is locked by another thread, including the current thread.231 *********************************************************************************************232 * @ mutex : pointer on mutex in user space.233 * @ return 0 if success / return -1 if mutex already taken.234 ********************************************************************************************/235 int pthread_mutex_trylock( pthread_mutex_t * mutex );236 237 238 //////////////////////////////////////////////////////////////////////////////////////////////239 // POSIX condvar related functions240 //////////////////////////////////////////////////////////////////////////////////////////////241 242 /*********************************************************************************************243 * This function initializes a condition variable identified by the <cond> argument.244 * WARNING: the <attr> argument is not supported and must be NULL.245 *********************************************************************************************246 * @ cond : [in] pointer on condition in user space.247 * @ attr : [in] pointer on condition attribute (must be NULL).248 * @ return 0 if success / return -1 if failure.249 ********************************************************************************************/250 int pthread_cond_init( pthread_cond_t * cond,251 pthread_condattr_t * attr );252 253 /*********************************************************************************************254 * This function atomically unlocks the <mutex> and blocks the calling thread on the255 * condition specified by the <cond> argument. The thread unblocks only after another256 * thread calls the pthread_cond_signal() or pthread_cond_broadcast() functions with the257 * same condition variable. The mutex must be locked before calling this function,258 * otherwise the behavior is undefined. Before the pthread_cond_wait() function returns259 * to the calling function, it re-acquires the <mutex>.260 *********************************************************************************************261 * @ cond : pointer on condition in user space.262 * @ mutex : pointer on mutex in user space.263 * @ return 0 if success / return -1 if failure.264 ********************************************************************************************/265 int pthread_cond_wait( pthread_cond_t * cond,266 pthread_mutex_t * mutex );267 268 /*********************************************************************************************269 * This function unblocks one thread blocked on condition specified by the <cond> argument.270 *********************************************************************************************271 * @ cond : pointer on condition in user space.272 * @ return 0 if success / return -1 if failure.273 ********************************************************************************************/274 int pthread_cond_signal( pthread_cond_t * cond );275 276 /*********************************************************************************************277 * This function unblocks all threads blocked on condition specified by the <cond> argument.278 *********************************************************************************************279 * @ cond : pointer on condition in user space.280 * @ return 0 if success / return -1 if failure.281 ********************************************************************************************/282 int pthread_cond_broadcast( pthread_cond_t * cond );283 284 /*********************************************************************************************285 * This function delete the condition variable specified by the <cond> argument.286 *********************************************************************************************287 * @ cond : pointer on condition in user space.288 * @ return 0 if success / return -1 if failure.289 ********************************************************************************************/290 int pthread_cond_destroy( pthread_cond_t * cond );291 292 293 240 294 241 #endif // _PTHREAD_H_ -
trunk/params-hard.mk
r580 r581 2 2 3 3 ARCH = /users/alain/soc/tsar-trunk-svn-2013/platforms/tsar_generic_iob 4 X_SIZE = 15 Y_SIZE = 16 NB_PROCS = 14 X_SIZE = 2 5 Y_SIZE = 2 6 NB_PROCS = 2 7 7 NB_TTYS = 3 8 8 FBF_WIDTH = 128 -
trunk/user/fft/fft.c
r574 r581 300 300 } 301 301 302 printf("\n[FFT]complete remote_malloc\n");302 printf("\n[FFT] main complete remote_malloc\n"); 303 303 304 304 // arrays initialisation … … 307 307 InitT( twid ); 308 308 309 printf("\n[FFT]complete init arrays\n");309 printf("\n[FFT] main complete init arrays\n"); 310 310 311 311 #if CHECK -
trunk/user/init/init.c
r574 r581 21 21 #include <sys/wait.h> 22 22 23 #define DEBUG_PROCESS_INIT 023 #define DEBUG_PROCESS_INIT 1 24 24 25 25 // TODO improve the get_config() syscall to return nb_txt_channels … … 53 53 for( i = 1 ; i < NB_TXT_CHANNELS ; i++ ) 54 54 { 55 56 #if DEBUG_PROCESS_INIT57 snprintf( string , 64 , "[INIT] start child[%d] creation" , i );58 display_string( string );59 #endif60 61 55 // INIT process fork process CHILD[i] 62 56 ret_fork = fork(); … … 108 102 for( x = 0 ; x < x_size ; x++ ) 109 103 { 110 cxy = HAL_CXY_FROM_XY( x , y ); 111 display_cluster_processes( cxy ); 112 for( lid = 0 ; lid < ncores ; lid++ ) 113 { 104 for( y = 0 ; y < x_size ; y++ ) 105 { 106 cxy = HAL_CXY_FROM_XY( x , y ); 114 107 display_cluster_processes( cxy ); 108 for( lid = 0 ; lid < ncores ; lid++ ) 109 { 110 display_sched( cxy , lid ); 111 } 115 112 } 116 113 } … … 173 170 } // end KSH kill handling 174 171 175 #if DEBUG_PROCESS_INIT176 177 // INIT displays processes and threads in all clusters178 for( x = 0 ; x < x_size ; x++ )179 {180 for( y = 0 ; y < y_size ; y++ )181 {182 cxy = HAL_CXY_FROM_XY( x , y );183 display_cluster_processes( cxy );184 for( lid = 0 ; lid < ncores ; lid++ )185 {186 display_sched( cxy , lid );187 }188 }189 }190 191 #endif192 193 172 } // end while waiting KSH[i] termination 194 173
Note: See TracChangeset
for help on using the changeset viewer.