Changeset 466 for soft/giet_vm/giet_common
- Timestamp:
- Dec 12, 2014, 4:55:06 PM (10 years ago)
- Location:
- soft/giet_vm/giet_common
- Files:
-
- 2 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/giet_common/locks.c
r455 r466 8 8 #include "locks.h" 9 9 #include "giet_config.h" 10 #include "hard_config.h" 10 11 #include "utils.h" 12 #include "tty0.h" 13 #include "kernel_malloc.h" 11 14 12 15 /////////////////////////////////////////////////// … … 32 35 } 33 36 34 //////////////////////////////////// 35 void _lock_init( spin_lock_t* lock ) 36 { 37 lock->current = 0; 38 lock->free = 0; 39 40 #if GIET_DEBUG_SYS_LOCK 37 /////////////////////////////////////////////////////////////////////////////////// 38 // Simple lock access functions 39 /////////////////////////////////////////////////////////////////////////////////// 40 41 //////////////////////////////////////////////// 42 void _simple_lock_acquire( simple_lock_t* lock ) 43 { 44 45 #if GIET_DEBUG_SIMPLE_LOCK 41 46 unsigned int gpid = _get_procid(); 42 47 unsigned int x = gpid >> (Y_WIDTH + P_WIDTH); 43 48 unsigned int y = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 44 49 unsigned int l = gpid & ((1<<P_WIDTH)-1); 45 _printf("\n[SYS_LOCK DEBUG] P[%d,%d,%d] init lock %x" 46 " at cycle %d (current = %d / free = %d)\n", 47 x, y, l, (unsigned int)lock, 48 _get_proctime(), lock->current, lock->free ); 49 #endif 50 51 } 52 53 54 //////////////////////////////////////// 55 void _lock_acquire( spin_lock_t* lock ) 56 { 57 // get next free slot index fromlock 58 unsigned int ticket = _atomic_increment( &lock->free, 1 ); 59 60 #if GIET_DEBUG_SYS_LOCK 61 unsigned int gpid = _get_procid(); 62 unsigned int x = gpid >> (Y_WIDTH + P_WIDTH); 63 unsigned int y = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 64 unsigned int l = gpid & ((1<<P_WIDTH)-1); 65 _printf("\n[SYS_LOCK DEBUG] P[%d,%d,%d] get ticket = %d" 66 " for lock %x at cycle %d (current = %d / free = %d)\n", 67 x, y, l, ticket, 68 (unsigned int)lock, _get_proctime(), lock->current, lock->free ); 69 #endif 70 71 72 // poll the spin_lock current slot index 73 asm volatile("5678: \n" 74 "lw $10, 0(%0) \n" 75 "move $11, %1 \n" 76 "bne $10, $11, 5678b \n" 77 : 78 : "r"(lock), "r"(ticket) 79 : "$10", "$11" ); 80 81 #if GIET_DEBUG_SYS_LOCK 82 _printf("\n[SYS_LOCK DEBUG] P[%d,%d,%d] get lock = %x" 83 " at cycle %d (current = %d / free = %d)\n", 84 x, y, l, (unsigned int)lock, 85 _get_proctime(), lock->current, lock->free ); 86 #endif 87 88 } 89 90 //////////////////////////////////////// 91 void _lock_release( spin_lock_t* lock ) 92 { 93 unsigned int current = lock->current; 94 95 if ( current == (GIET_LOCK_MAX_TICKET - 1) ) current = 0; 96 else current = current + 1; 97 98 asm volatile ( "sync \n" /* for consistency */ 99 "sw %1, 0(%0) \n" /* release lock */ 100 : 101 : "r"(lock), "r"(current) 102 : "memory" ); 103 104 105 #if GIET_DEBUG_SYS_LOCK 106 unsigned int gpid = _get_procid(); 107 unsigned int x = gpid >> (Y_WIDTH + P_WIDTH); 108 unsigned int y = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 109 unsigned int l = gpid & ((1<<P_WIDTH)-1); 110 _printf("\n[SYS_LOCK DEBUG] P[%d,%d,%d] release lock = %x" 111 " at cycle %d (current = %d / free = %d)\n", 112 x, y, l, (unsigned int)lock, 113 _get_proctime(), lock->current, lock->free ); 114 #endif 115 116 } 117 118 119 120 121 122 123 124 125 //////////////////////////////////////////////// 126 void _simple_lock_acquire( simple_lock_t* lock ) 127 { 50 _nolock_printf("\n[DEBUG SIMPLE_LOCK] P[%d,%d,%d] enters acquire() at cycle %d\n", 51 x , y , l , _get_proctime() ); 52 #endif 53 128 54 asm volatile ( "1515: \n" 129 55 "lw $2, 0(%0) \n" /* $2 <= lock current value */ … … 137 63 : "r"(lock) 138 64 : "$2", "$3", "memory" ); 65 66 #if GIET_DEBUG_SIMPLE_LOCK 67 _nolock_printf("\n[DEBUG SIMPLE_LOCK] P[%d,%d,%d] exit acquire() at cycle %d\n", 68 x , y , l , _get_proctime() ); 69 #endif 70 139 71 } 140 72 … … 147 79 : "r"(lock) 148 80 : "memory" ); 149 } 150 81 82 #if GIET_DEBUG_SIMPLE_LOCK 83 unsigned int gpid = _get_procid(); 84 unsigned int x = gpid >> (Y_WIDTH + P_WIDTH); 85 unsigned int y = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 86 unsigned int l = gpid & ((1<<P_WIDTH)-1); 87 _nolock_printf("\n[DEBUG SIMPLE_LOCK] P[%d,%d,%d] release() at cycle %d\n", 88 x , y , l , _get_proctime() ); 89 #endif 90 91 } 92 93 94 /////////////////////////////////////////////////////////////////////////////////// 95 // Queuing Lock access functions 96 /////////////////////////////////////////////////////////////////////////////////// 97 98 ///////////////////////////////////////// 99 void _spin_lock_init( spin_lock_t* lock ) 100 { 101 lock->current = 0; 102 lock->free = 0; 103 104 #if GIET_DEBUG_SPIN_LOCK 105 unsigned int gpid = _get_procid(); 106 unsigned int x = gpid >> (Y_WIDTH + P_WIDTH); 107 unsigned int y = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 108 unsigned int l = gpid & ((1<<P_WIDTH)-1); 109 _puts("\n[DEBUG SPIN_LOCK] P["); 110 _putd( x ); 111 _puts(","); 112 _putd( y ); 113 _puts(","); 114 _putd( l ); 115 _puts("] init lock "); 116 _putx( (unsigned int)lock ); 117 _puts(" (current = "); 118 _putd( lock->current ); 119 _puts(" / free = "); 120 _putd( lock->free ); 121 _puts(" )\n"); 122 #endif 123 124 } 125 126 127 //////////////////////////////////////////// 128 void _spin_lock_acquire( spin_lock_t* lock ) 129 { 130 // get next free slot index fromlock 131 unsigned int ticket = _atomic_increment( &lock->free, 1 ); 132 133 #if GIET_DEBUG_SPIN_LOCK 134 unsigned int gpid = _get_procid(); 135 unsigned int x = gpid >> (Y_WIDTH + P_WIDTH); 136 unsigned int y = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 137 unsigned int l = gpid & ((1<<P_WIDTH)-1); 138 _puts("\n[DEBUG SPIN_LOCK] P["); 139 _putd( x ); 140 _puts(","); 141 _putd( y ); 142 _puts(","); 143 _putd( l ); 144 _puts("] get ticket "); 145 _putx( ticket ); 146 _puts(" for lock "); 147 _putx( (unsigned int)lock ); 148 _puts(" (current = "); 149 _putd( lock->current ); 150 _puts(" / free = "); 151 _putd( lock->free ); 152 _puts(" )\n"); 153 #endif 154 155 156 // poll the spin_lock current slot index 157 asm volatile("5678: \n" 158 "lw $10, 0(%0) \n" 159 "move $11, %1 \n" 160 "bne $10, $11, 5678b \n" 161 : 162 : "r"(lock), "r"(ticket) 163 : "$10", "$11" ); 164 165 #if GIET_DEBUG_SPIN_LOCK 166 _puts("\n[DEBUG SPIN_LOCK] P["); 167 _putd( x ); 168 _puts(","); 169 _putd( y ); 170 _puts(","); 171 _putd( l ); 172 _puts("] get lock "); 173 _putx( (unsigned int)lock ); 174 _puts(" (current = "); 175 _putd( lock->current ); 176 _puts(" / free = "); 177 _putd( lock->free ); 178 _puts(" )\n"); 179 #endif 180 181 } 182 183 //////////////////////////////////////////// 184 void _spin_lock_release( spin_lock_t* lock ) 185 { 186 unsigned int current = lock->current; 187 188 if ( current == (GIET_LOCK_MAX_TICKET - 1) ) current = 0; 189 else current = current + 1; 190 191 asm volatile ( "sync \n" /* for consistency */ 192 "sw %1, 0(%0) \n" /* release lock */ 193 : 194 : "r"(lock), "r"(current) 195 : "memory" ); 196 197 198 #if GIET_DEBUG_SPIN_LOCK 199 unsigned int gpid = _get_procid(); 200 unsigned int x = gpid >> (Y_WIDTH + P_WIDTH); 201 unsigned int y = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 202 unsigned int l = gpid & ((1<<P_WIDTH)-1); 203 _puts("\n[DEBUG SPIN_LOCK] P["); 204 _putd( x ); 205 _puts(","); 206 _putd( y ); 207 _puts(","); 208 _putd( l ); 209 _puts("] release lock "); 210 _putx( (unsigned int)lock ); 211 _puts(" (current = "); 212 _putd( lock->current ); 213 _puts(" / free = "); 214 _putd( lock->free ); 215 _puts(" )\n"); 216 #endif 217 218 } 219 220 /////////////////////////////////////////////////////////////////////////////////// 221 // SBT lock access functions 222 /////////////////////////////////////////////////////////////////////////////////// 223 224 /////////////////////////////////////////////////////////////////////////////////// 225 // This recursive function is used by the _sbt_lock_init() function 226 // to initializes the SBT nodes (mainly the parent and child pointers). 227 // It traverses the SBT from top to bottom. 228 /////////////////////////////////////////////////////////////////////////////////// 229 static void _sbt_lock_build( sbt_lock_t* lock, // pointer on the SBT lock 230 unsigned int x, // SBT node x coordinate 231 unsigned int y, // SBT node y coordinate 232 unsigned int level, // SBT node level 233 lock_node_t* parent ) // pointer on parent node 234 { 235 236 #if GIET_DEBUG_SBT_LOCK 237 unsigned int gpid = _get_procid(); 238 unsigned int px = gpid >> (Y_WIDTH + P_WIDTH); 239 unsigned int py = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 240 unsigned int pl = gpid & ((1<<P_WIDTH)-1); 241 #endif 242 243 // get target node pointer 244 lock_node_t* node = lock->node[x][y][level]; 245 246 if (level == 0 ) // terminal case 247 { 248 // initializes target node 249 node->taken = 0; 250 node->level = level; 251 node->parent = parent; 252 node->child0 = NULL; 253 node->child1 = NULL; 254 node->x = x; 255 node->y = y; 256 257 #if GIET_DEBUG_SBT_LOCK 258 _nolock_printf("\n[DEBUG SBT_LOCK] P[%d,%d,%d] initialises SBT node[%d,%d,%d] : " 259 "parent = %x / childO = %x / child1 = %x\n", 260 px , py , pl , node->x , node->y , node->level , 261 (unsigned int)node->parent , (unsigned int)node->child0 , (unsigned int)node->child1 ); 262 #endif 263 264 } 265 else // non terminal case 266 { 267 unsigned int x0; // x coordinate for child0 268 unsigned int y0; // y coordinate for child0; 269 unsigned int x1; // x coordinate for child1; 270 unsigned int y1; // y coordinate for child1; 271 272 // the child0 coordinates are equal to the parent coordinates 273 // the child1 coordinates are incremented depending on the level value 274 if ( level & 0x1 ) // odd level => X binary tree 275 { 276 x0 = x; 277 y0 = y; 278 x1 = x + (1 << ((level-1)>>1)); 279 y1 = y; 280 } 281 else // even level => Y binary tree 282 { 283 x0 = x; 284 y0 = y; 285 x1 = x; 286 y1 = y + (1 << ((level-1)>>1)); 287 } 288 289 // initializes target node 290 node->taken = 0; 291 node->level = level; 292 node->parent = parent; 293 node->child0 = lock->node[x0][y0][level-1]; 294 node->child1 = lock->node[x1][y1][level-1]; 295 296 #if GIET_DEBUG_SBT_LOCK 297 _nolock_printf("\n[DEBUG SBT_LOCK] P[%d,%d,%d] initialises SBT node[%d,%d,%d] : " 298 "parent = %x / childO = %x / child1 = %x\n", 299 px , py , pl , x , y , level , 300 (unsigned int)node->parent , (unsigned int)node->child0 , (unsigned int)node->child1 ); 301 #endif 302 303 // recursive calls for children nodes 304 _sbt_lock_build( lock , x0 , y0 , level-1 , node ); 305 _sbt_lock_build( lock , x1 , y1 , level-1 , node ); 306 } 307 308 } // end _sbt_lock_build() 309 310 ////////////////////////////////////////////////////////////////////////////////// 311 // This recursive function is used by the sbt_lock_acquire() function to 312 // get the SBT lock: It tries to get each "partial" lock on the path from bottom 313 // to top, using an atomic LL/SC, and starting from bottom. 314 // It is blocking : it poll each "partial lock until it can be taken. 315 // The lock is finally obtained when all "partial" locks, at all levels are taken. 316 ////////////////////////////////////////////////////////////////////////////////// 317 static void _sbt_lock_take( lock_node_t* node ) 318 { 319 // try to take "partial" lock 320 unsigned int* taken = &node->taken; 321 322 asm volatile ( "1945: \n" 323 "lw $2, 0(%0) \n" /* $2 <= lock current value */ 324 "bnez $2, 1945b \n" /* retry if lock already taken */ 325 "ll $2, 0(%0) \n" /* ll_buffer <= lock current value */ 326 "bnez $2, 1945b \n" /* retry if lock already taken */ 327 "li $3, 1 \n" /* $3 <= argument for sc */ 328 "sc $3, 0(%0) \n" /* try to set lock */ 329 "beqz $3, 1945b \n" /* retry if sc failure */ 330 : 331 : "r"(taken) 332 : "$2", "$3", "memory" ); 333 334 #if GIET_DEBUG_SBT_LOCK 335 unsigned int gpid = _get_procid(); 336 unsigned int px = gpid >> (Y_WIDTH + P_WIDTH); 337 unsigned int py = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 338 unsigned int pl = gpid & ((1<<P_WIDTH)-1); 339 _nolock_printf("\n[DEBUG SBT_LOCK] P[%d,%d,%d] get partial SBT lock[%d,%d,%d] : vaddr = %x\n", 340 px , py , pl , node->x , node->y , node->level , (unsigned int)node ); 341 #endif 342 343 // try to take the parent node lock until top is reached 344 if ( node->parent != NULL ) _sbt_lock_take( node->parent ); 345 346 } // end _sbt_lock_take() 347 348 349 ///////////////////////////////////////////////////////////////////////////////// 350 // This recursive function is used by the sbt_lock_release() function to 351 // release the SBT lock: It reset all "partial" locks on the path from bottom 352 // to top, using a normal write, and starting from bottom. 353 ///////////////////////////////////////////////////////////////////////////////// 354 static void _sbt_lock_free( lock_node_t* node ) 355 { 356 // reset "partial" lock 357 node->taken = 0; 358 359 #if GIET_DEBUG_SBT_LOCK 360 unsigned int gpid = _get_procid(); 361 unsigned int px = gpid >> (Y_WIDTH + P_WIDTH); 362 unsigned int py = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 363 unsigned int pl = gpid & ((1<<P_WIDTH)-1); 364 _nolock_printf("\n[DEBUG SBT_LOCK] P[%d,%d,%d] release partial SBT lock[%d,%d,%d] : vaddr = %x\n", 365 px , py , pl , node->x , node->y , node->level , (unsigned int)node ); 366 #endif 367 368 // reset parent node until top is reached 369 if ( node->parent != NULL ) _sbt_lock_free( node->parent ); 370 371 } // end _sbt_lock_free() 372 373 ////////////////////////////////////////////////////////////////////////////////// 374 // This external function initialises the distributed SBT lock. 375 ////////////////////////////////////////////////////////////////////////////////// 376 void _sbt_lock_init( sbt_lock_t* lock ) 377 { 378 unsigned int levels = 0; // depth of the SBT (number of levels) 379 380 // compute SBT levels 381 if ((X_SIZE == 1 ) && (Y_SIZE == 1 )) levels = 1; 382 else if ((X_SIZE == 2 ) && (Y_SIZE == 1 )) levels = 2; 383 else if ((X_SIZE == 2 ) && (Y_SIZE == 2 )) levels = 3; 384 else if ((X_SIZE == 4 ) && (Y_SIZE == 2 )) levels = 4; 385 else if ((X_SIZE == 4 ) && (Y_SIZE == 4 )) levels = 5; 386 else if ((X_SIZE == 8 ) && (Y_SIZE == 4 )) levels = 6; 387 else if ((X_SIZE == 8 ) && (Y_SIZE == 8 )) levels = 7; 388 else if ((X_SIZE == 16) && (Y_SIZE == 8 )) levels = 8; 389 else if ((X_SIZE == 16) && (Y_SIZE == 16)) levels = 9; 390 else 391 { 392 _nolock_printf("\n[GIET ERROR] _sbt_lock_init() :illegal X_SIZE/Y_SIZE \n"); 393 _exit(); 394 } 395 396 #if GIET_DEBUG_SBT_LOCK 397 unsigned int gpid = _get_procid(); 398 unsigned int px = gpid >> (Y_WIDTH + P_WIDTH); 399 unsigned int py = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 400 unsigned int pl = gpid & ((1<<P_WIDTH)-1); 401 _nolock_printf("\n[DEBUG SBT_LOCK] P[%d,%d,%d] initialises SBT lock %x : %d levels\n", 402 px , py , pl , (unsigned int)lock , levels ); 403 #endif 404 405 // allocates memory for the SBT nodes and initializes SBT nodes pointers array 406 // the actual number of SBT nodes in a cluster(x,y) depends on (x,y): 407 // At least 1 node / at most 9 nodes per cluster. 408 unsigned int x; // x coordinate for one SBT node 409 unsigned int y; // y coordinate for one SBT node 410 unsigned int l; // level for one SBT node 411 for ( x = 0 ; x < X_SIZE ; x++ ) 412 { 413 for ( y = 0 ; y < Y_SIZE ; y++ ) 414 { 415 for ( l = 0 ; l < levels ; l++ ) // level 0 nodes 416 { 417 418 if ( ( (l == 0) && ((x&0x00) == 0) && ((y&0x00) == 0) ) || 419 ( (l == 1) && ((x&0x01) == 0) && ((y&0x00) == 0) ) || 420 ( (l == 2) && ((x&0x01) == 0) && ((y&0x01) == 0) ) || 421 ( (l == 3) && ((x&0x03) == 0) && ((y&0x01) == 0) ) || 422 ( (l == 4) && ((x&0x03) == 0) && ((y&0x03) == 0) ) || 423 ( (l == 5) && ((x&0x07) == 0) && ((y&0x03) == 0) ) || 424 ( (l == 6) && ((x&0x07) == 0) && ((y&0x07) == 0) ) || 425 ( (l == 7) && ((x&0x0F) == 0) && ((y&0x07) == 0) ) || 426 ( (l == 8) && ((x&0x0F) == 0) && ((y&0x0F) == 0) ) ) 427 { 428 lock->node[x][y][l] = (lock_node_t*)_remote_malloc( sizeof(lock_node_t), 429 x, y ); 430 431 #if GIET_DEBUG_SBT_LOCK 432 _nolock_printf("\n[DEBUG SBT_LOCK] P[%d,%d,%d] allocates SBT node[%d,%d,%d] : vaddr = %x\n", 433 px , py , pl , x , y , l , (unsigned int)lock->node[x][y][l] ); 434 #endif 435 } 436 } 437 } 438 } 439 440 #if GIET_DEBUG_SBT_LOCK 441 _nolock_printf("\n[DEBUG SBT_LOCK] SBT nodes initialisation starts\n"); 442 #endif 443 444 // recursively initialize all SBT nodes from root to bottom 445 _sbt_lock_build( lock, // pointer on the SBT lock descriptor 446 0, // x coordinate 447 0, // y coordinate 448 levels-1, // level in SBT 449 NULL ); // pointer on the parent node 450 451 asm volatile ("sync" ::: "memory"); 452 453 #if GIET_DEBUG_SBT_LOCK 454 _nolock_printf("\n[DEBUG SBT_LOCK] SBT nodes initialisation completed\n"); 455 #endif 456 457 } // end _sbt_lock_init() 458 459 ////////////////////////////////////////////////////////////////////////////////// 460 // This external function get thes SBT lock. 461 // Returns only when the lock has been taken. 462 ///////////////////////////////////////////////////////////////////////////////// 463 void _sbt_lock_acquire( sbt_lock_t* lock ) 464 { 465 // get cluster coordinates 466 unsigned int gpid = _get_procid(); 467 unsigned int x = (gpid >> (Y_WIDTH + P_WIDTH)) & ((1<<X_WIDTH)-1); 468 unsigned int y = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 469 470 // try to recursively take the "partial" locks (from bottom to top) 471 _sbt_lock_take( lock->node[x][y][0] ); 472 } 473 474 475 ///////////////////////////////////////////////////////////////////////////////// 476 // This external function releases the SBT lock. 477 ///////////////////////////////////////////////////////////////////////////////// 478 void _sbt_lock_release( sbt_lock_t* lock ) 479 { 480 // get cluster coordinates 481 unsigned int gpid = _get_procid(); 482 unsigned int x = (gpid >> (Y_WIDTH + P_WIDTH)) & ((1<<X_WIDTH)-1); 483 unsigned int y = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 484 485 // recursively reset the "partial" locks (from bottom to top) 486 _sbt_lock_free( lock->node[x][y][0] ); 487 } 151 488 152 489 // Local Variables: -
soft/giet_vm/giet_common/locks.h
r455 r466 6 6 /////////////////////////////////////////////////////////////////////////////////// 7 7 // The locks.c and locks.h files are part of the GIET-VM nano-kernel. 8 // They define both atomic increment operations and locks. 9 // The locks used gy the GIET_VM are spin-locks with a waiting queue. 8 // They define both atomic increment operations and three types of locks. 10 9 /////////////////////////////////////////////////////////////////////////////////// 11 10 … … 13 12 #define GIET_LOCKS_H 14 13 14 #include "hard_config.h" 15 15 16 /////////////////////////////////////////////////////////////////////////////////// 16 // This structure implements a spin-lock with waiting file. 17 // There is at most one lock per cache line. 17 // Simple lock structure and access functions 18 /////////////////////////////////////////////////////////////////////////////////// 19 20 typedef struct simple_lock_s 21 { 22 unsigned int value; // lock taken if non zero 23 unsigned int padding[15]; // for 64 bytes alignment 24 } simple_lock_t; 25 26 extern void _simple_lock_acquire( simple_lock_t* lock ); 27 28 extern void _simple_lock_release( simple_lock_t* lock ); 29 30 /////////////////////////////////////////////////////////////////////////////////// 31 // Queuing lock structure and access functions 18 32 /////////////////////////////////////////////////////////////////////////////////// 19 33 … … 21 35 { 22 36 unsigned int current; // current slot index 23 unsigned int free; // next free slot index37 unsigned int free; // next free tiket index 24 38 unsigned int padding[14]; // for 64 bytes alignment 25 39 } spin_lock_t; 26 27 typedef struct simple_lock_s28 {29 unsigned int value;30 unsigned int padding[15];31 } simple_lock_t;32 33 ///////////////////////////////////////////////////////////////////////////////////34 // Locks access functions35 ///////////////////////////////////////////////////////////////////////////////////36 40 37 41 extern unsigned int _atomic_increment( unsigned int* ptr, 38 42 unsigned int increment ); 39 43 40 extern void _ lock_init( spin_lock_t* lock );44 extern void _spin_lock_init( spin_lock_t* lock ); 41 45 42 extern void _ lock_acquire( spin_lock_t* lock );46 extern void _spin_lock_acquire( spin_lock_t* lock ); 43 47 44 extern void _ lock_release( spin_lock_t* lock );48 extern void _spin_lock_release( spin_lock_t* lock ); 45 49 46 extern void _simple_lock_acquire( simple_lock_t* lock ); 50 ////////////////////////////////////////////////////////////////////////////////// 51 // SBT lock structures and access functions 52 ////////////////////////////////////////////////////////////////////////////////// 47 53 48 extern void _simple_lock_release( simple_lock_t* lock ); 54 typedef struct lock_node_s 55 { 56 unsigned int taken; // lock taken if non zero 57 unsigned int level; // hierarchical level (0 is bottom) 58 struct lock_node_s* parent; // pointer on parent node (NULL for root) 59 struct lock_node_s* child0; // pointer on children node 60 struct lock_node_s* child1; // pointer on children node 61 unsigned int x; // cluster x coordinate 62 unsigned int y; // cluster y coordinate 63 unsigned int padding[9]; // for 64 bytes alignment 64 } lock_node_t; 65 66 typedef struct sbt_lock_s 67 { 68 unsigned int ntasks; // total number of expected tasks 69 lock_node_t* node[X_SIZE][Y_SIZE][9]; // array of pointers on SBT nodes 70 } sbt_lock_t; 71 72 extern void _sbt_lock_init( sbt_lock_t* lock ); 73 74 extern void _sbt_lock_acquire( sbt_lock_t* lock ); 75 76 extern void _sbt_lock_release( sbt_lock_t* lock ); 49 77 50 78 #endif -
soft/giet_vm/giet_common/tty0.c
r455 r466 10 10 #include <hard_config.h> 11 11 #include <tty0.h> 12 #include <stdarg.h> 12 13 #include <tty_driver.h> 13 #include <stdarg.h>14 14 #include <utils.h> 15 15 #include <locks.h> … … 114 114 } 115 115 116 ////////////////////////////////// 117 void _printf( char * format, ... ) 118 { 119 va_list ap; 120 va_start(ap, format); 121 unsigned int save_sr; // to save SR value in critical section 122 123 // get TTY lock 124 _it_disable( &save_sr ); 125 _simple_lock_acquire( &_tty_tx_lock[0] ); 116 ////////////////////////////////////////////////////////// 117 static void _kernel_printf( char * format, va_list* args ) 118 { 126 119 127 120 printf_text: … … 143 136 } 144 137 145 // release TTY lock146 _simple_lock_release( &_tty_tx_lock[0] );147 _it_restore( &save_sr );148 149 va_end(ap);150 138 return; 151 139 … … 163 151 case ('c'): /* char conversion */ 164 152 { 165 int val = va_arg( ap, int );153 int val = va_arg( *args , int ); 166 154 len = 1; 167 155 buf[0] = val; … … 171 159 case ('d'): /* 32 bits decimal signed */ 172 160 { 173 int val = va_arg( ap, int );161 int val = va_arg( *args , int ); 174 162 if (val < 0) 175 163 { … … 188 176 case ('u'): /* 32 bits decimal unsigned */ 189 177 { 190 unsigned int val = va_arg( ap, unsigned int );178 unsigned int val = va_arg( *args , unsigned int ); 191 179 for(i = 0; i < 10; i++) 192 180 { … … 200 188 case ('x'): /* 32 bits hexadecimal unsigned */ 201 189 { 202 unsigned int val = va_arg( ap, unsigned int );190 unsigned int val = va_arg( *args , unsigned int ); 203 191 if ( _tty0_write( "0x" , 2 ) ) goto return_error; 204 192 for(i = 0; i < 8; i++) … … 213 201 case ('l'): /* 64 bits hexadecimal unsigned */ 214 202 { 215 unsigned long long val = va_arg( ap, unsigned long long );203 unsigned long long val = va_arg( *args , unsigned long long ); 216 204 if ( _tty0_write( "0x" , 2 ) ) goto return_error; 217 205 for(i = 0; i < 16; i++) … … 226 214 case ('s'): /* string */ 227 215 { 228 char* str = va_arg( ap, char* );216 char* str = va_arg( *args , char* ); 229 217 while (str[len]) 230 218 { … … 246 234 247 235 { 248 // release TTY lock 249 _simple_lock_release( &_tty_tx_lock[0] ); 250 _it_restore( &save_sr ); 251 252 // try to print a non protected error message... 236 // try to print an error message and exit... 253 237 unsigned int procid = _get_procid(); 254 238 unsigned int x = (procid >> (Y_WIDTH + P_WIDTH)) & ((1<<X_WIDTH)-1); 255 239 unsigned int y = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 256 240 unsigned int lpid = procid & ((1<<P_WIDTH)-1); 257 258 241 _puts("\n\n[GIET ERROR] in _printf() for processor["); 259 242 _putd( x ); … … 266 249 _exit(); 267 250 } 268 } // end _printf() 251 } // end _kernel_printf() 252 253 /////////////////////////////////////// 254 void _nolock_printf( char* format, ...) 255 { 256 va_list args; 257 258 va_start( args , format ); 259 _kernel_printf( format , &args ); 260 va_end( args ); 261 } 262 //////////////////////////////// 263 void _printf( char* format, ...) 264 { 265 va_list args; 266 unsigned int save_sr; 267 268 // get TTY0 lock 269 _it_disable( &save_sr ); 270 _sbt_lock_acquire( &_tty_tx_lock[0] ); 271 272 va_start( args , format ); 273 _kernel_printf( format , &args ); 274 va_end( args ); 275 276 // release TTY0 lock 277 _sbt_lock_release( &_tty_tx_lock[0] ); 278 _it_restore( &save_sr ); 279 } 269 280 270 281 -
soft/giet_vm/giet_common/tty0.h
r455 r466 27 27 extern void _getc( char* byte ); 28 28 29 extern void _nolock_printf( char* format, ... ); 30 29 31 extern void _printf( char* format, ... ); 30 32 -
soft/giet_vm/giet_common/utils.c
r455 r466 622 622 asm volatile( "move $3, %0 \n" 623 623 "loop_nic_completed: \n" 624 "nop \n" 624 625 "addi $3, $3, -1 \n" 625 626 "bnez $3, loop_nic_completed \n"
Note: See TracChangeset
for help on using the changeset viewer.