Changeset 635 for trunk/kernel/libk
- Timestamp:
- Jun 26, 2019, 11:42:37 AM (5 years ago)
- Location:
- trunk/kernel/libk
- Files:
-
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/libk/bits.c
r473 r635 3 3 * 4 4 * Author Ghassan Almaless (2008,2009,2010,2011,2012) 5 * Alain Greiner (2016 )5 * Alain Greiner (2016,2017,2018,2019) 6 6 * 7 7 * Copyright (c) UPMC Sorbonne Universites -
trunk/kernel/libk/bits.h
r457 r635 3 3 * 4 4 * Author Ghassan Almaless (2008,2009,2010,2011,2012) 5 * Alain Greiner (2016 )5 * Alain Greiner (2016,2017,2018,2019) 6 6 * 7 7 * Copyright (c) UPMC Sorbonne Universites … … 189 189 190 190 /********************************************************************************************* 191 * This function returns the number of bits to code a non-zero unsigned integer value. 192 ********************************************************************************************* 193 * @ val : value to analyse 194 * @ returns number of bits 195 ********************************************************************************************/ 196 static inline uint32_t bits_nr( uint32_t val ) 197 { 198 register uint32_t i; 199 200 for( i=0 ; val > 0 ; i++ ) 201 val = val >> 1; 202 203 return i; 204 } 205 206 /********************************************************************************************* 207 * This function takes an unsigned integer value as input argument, and returns another 208 * unsigned integer, that is the (base 2) logarithm of the smallest power of 2 contained 209 * in the input value. 191 * This function takes a positive integer <val> as input argument, and returns the smallest 192 * integer <order> such as : 1<<order >= val. 193 * In other words, <order> is the min number of bits to encode <val> values. 210 194 ********************************************************************************************* 211 195 * @ val : value to analyse … … 214 198 static inline uint32_t bits_log2( uint32_t val ) 215 199 { 216 return (val == 0) ? 1 : bits_nr( val ) - 1; 200 uint32_t i; 201 202 if( val > 0 ) 203 { 204 val--; 205 for( i=0 ; val > 0 ; i++ ) val = val >> 1; 206 return i; 207 } 208 return 0; 217 209 } 218 210 -
trunk/kernel/libk/elf.c
r625 r635 2 2 * elf.c - elf parser: find and map process CODE and DATA segments 3 3 * 4 * Authors Alain Greiner (2016 )4 * Authors Alain Greiner (2016,2017,2018,2019) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 201 201 printk("\n[%s] thread[%x,%x] found %s vseg / base %x / size %x\n" 202 202 " file_size %x / file_offset %x / mapper_xp %l / cycle %d\n", 203 __FUNCTION__ , this->process _pid, this->trdid,203 __FUNCTION__ , this->process->pid, this->trdid, 204 204 vseg_type_str(vseg->type) , vseg->min , vseg->max - vseg->min , 205 vseg->file_size , vseg->file_offset , vseg->mapper_xp );205 vseg->file_size , vseg->file_offset , vseg->mapper_xp, cycle ); 206 206 #endif 207 207 … … 262 262 263 263 // allocate memory for segment descriptors array 264 req.type = KMEM_ GENERIC;265 req. size = segs_size;264 req.type = KMEM_KCM; 265 req.order = bits_log2(segs_size); 266 266 req.flags = AF_KERNEL; 267 267 segs_base = kmem_alloc( &req ); -
trunk/kernel/libk/grdxt.c
r626 r635 30 30 #include <grdxt.h> 31 31 32 //////////////////////////////////////////////////////////////////////////////////////// 33 // Local access functions 34 //////////////////////////////////////////////////////////////////////////////////////// 35 32 36 ///////////////////////////////// 33 37 error_t grdxt_init( grdxt_t * rt, … … 44 48 45 49 // allocates first level array 46 req.type = KMEM_ GENERIC;47 req. size = sizeof(void *) << ix1_width;50 req.type = KMEM_KCM; 51 req.order = ix1_width + ( (sizeof(void*) == 4) ? 2 : 3 ); 48 52 req.flags = AF_KERNEL | AF_ZERO; 49 53 root = kmem_alloc( &req ); 50 if( root == NULL ) return ENOMEM; 54 55 if( root == NULL ) 56 { 57 printk("\n[ERROR] in %s : cannot allocate first level array\n", __FUNCTION__); 58 return -1; 59 } 51 60 52 61 rt->root = root; … … 71 80 uint32_t ix1; 72 81 uint32_t ix2; 73 74 // check rt 82 uint32_t ix3; 83 75 84 assert( (rt != NULL) , "pointer on radix tree is NULL\n" ); 76 77 req.type = KMEM_GENERIC;78 85 79 86 for( ix1=0 ; ix1 < (uint32_t)(1 << w1) ; ix1++ ) … … 89 96 if( ptr3 == NULL ) continue; 90 97 98 for( ix3=0 ; ix3 < (uint32_t)(1 << w3) ; ix3++ ) 99 { 100 if( ptr3[ix3] != NULL ) 101 { 102 printk("\n[WARNING] in %s : ptr3[%d][%d][%d] non empty\n", 103 __FUNCTION__, ix1, ix2, ix3 ); 104 } 105 } 106 91 107 // release level 3 array 108 req.type = KMEM_KCM; 92 109 req.ptr = ptr3; 93 req.type = KMEM_GENERIC;94 req.size = sizeof(void *) * (1 << w3);95 110 kmem_free( &req ); 96 111 } 97 112 98 113 // release level 2 array 114 req.type = KMEM_KCM; 99 115 req.ptr = ptr2; 100 req.type = KMEM_GENERIC;101 req.size = sizeof(void *) * (1 << w2);102 116 kmem_free( &req ); 103 117 } 104 118 105 119 // release level 1 array 120 req.type = KMEM_KCM; 106 121 req.ptr = ptr1; 107 req.type = KMEM_GENERIC;108 req.size = sizeof(void *) * (1 << w1);109 122 kmem_free( &req ); 110 123 111 124 } // end grdxt_destroy() 112 113 ////////////////////////////////////114 void grdxt_display( xptr_t rt_xp,115 char * name )116 {117 uint32_t ix1;118 uint32_t ix2;119 uint32_t ix3;120 121 // check rt_xp122 assert( (rt_xp != XPTR_NULL) , "pointer on radix tree is NULL\n" );123 124 // get cluster and local pointer on remote rt descriptor125 grdxt_t * rt_ptr = GET_PTR( rt_xp );126 cxy_t rt_cxy = GET_CXY( rt_xp );127 128 // get widths129 uint32_t w1 = hal_remote_l32( XPTR( rt_cxy , &rt_ptr->ix1_width ) );130 uint32_t w2 = hal_remote_l32( XPTR( rt_cxy , &rt_ptr->ix2_width ) );131 uint32_t w3 = hal_remote_l32( XPTR( rt_cxy , &rt_ptr->ix3_width ) );132 133 void ** ptr1 = hal_remote_lpt( XPTR( rt_cxy , &rt_ptr->root ) );134 135 printk("\n***** Generic Radix Tree for <%s>\n", name );136 137 for( ix1=0 ; ix1 < (uint32_t)(1<<w1) ; ix1++ )138 {139 void ** ptr2 = hal_remote_lpt( XPTR( rt_cxy , &ptr1[ix1] ) );140 if( ptr2 == NULL ) continue;141 142 for( ix2=0 ; ix2 < (uint32_t)(1<<w2) ; ix2++ )143 {144 void ** ptr3 = hal_remote_lpt( XPTR( rt_cxy , &ptr2[ix2] ) );145 if( ptr3 == NULL ) continue;146 147 for( ix3=0 ; ix3 < (uint32_t)(1<<w3) ; ix3++ )148 {149 void * value = hal_remote_lpt( XPTR( rt_cxy , &ptr3[ix3] ) );150 if( value == NULL ) continue;151 152 uint32_t key = (ix1<<(w2+w3)) + (ix2<<w3) + ix3;153 printk(" - key = %x / value = %x\n", key , (intptr_t)value );154 }155 }156 }157 158 } // end grdxt_display()159 125 160 126 //////////////////////////////////// … … 177 143 uint32_t ix3 = key & ((1 << w3) - 1); // index in level 3 array 178 144 179 void ** ptr1 = rt->root; // pointer on level 1 array 180 void ** ptr2; // pointer on level 2 array 181 void ** ptr3; // pointer on level 3 array 182 183 // If required, we must allocate memory for the selected level 2 array, 184 // and update the level 1 array. 185 if( ptr1[ix1] == NULL ) 145 // get ptr1 146 void ** ptr1 = rt->root; 147 148 if( ptr1 == NULL ) return -1; 149 150 // get ptr2 151 void ** ptr2 = ptr1[ix1]; 152 153 // If required, allocate memory for the missing level 2 array 154 if( ptr2 == NULL ) 186 155 { 187 156 // allocate memory for level 2 array 188 req.type = KMEM_GENERIC;189 req. size = sizeof(void *) << w2;157 req.type = KMEM_KCM; 158 req.order = w2 + ( (sizeof(void*) == 4) ? 2 : 3 ); 190 159 req.flags = AF_KERNEL | AF_ZERO; 191 160 ptr2 = kmem_alloc( &req ); 192 if( ptr2 == NULL) return ENOMEM; 161 162 if( ptr2 == NULL) return -1; 193 163 194 164 // update level 1 array 195 165 ptr1[ix1] = ptr2; 196 166 } 197 else // get pointer on selected level 2 array. 198 { 199 ptr2 = ptr1[ix1]; 200 } 201 202 // If required, we must allocate memory for the selected level 3 array, 203 // and update the level 2 array. 204 if( ptr2[ix2] == NULL ) 167 168 // get ptr3 169 void ** ptr3 = ptr2[ix2]; 170 171 // If required, allocate memory for the missing level 3 array 172 if( ptr3 == NULL ) 205 173 { 206 174 // allocate memory for level 3 array 207 req.type = KMEM_ GENERIC;208 req. size = sizeof(void *) << w3;175 req.type = KMEM_KCM; 176 req.order = w3 + ( (sizeof(void*) == 4) ? 2 : 3 ); 209 177 req.flags = AF_KERNEL | AF_ZERO; 210 178 ptr3 = kmem_alloc( &req ); 211 if( ptr3 == NULL) return ENOMEM; 179 180 if( ptr3 == NULL) return -1; 212 181 213 182 // update level 3 array 214 183 ptr2[ix2] = ptr3; 215 184 } 216 else // get pointer on selected level 3 array.217 {218 ptr3 = ptr2[ix2];219 }220 221 // selected slot in level 3 array must be empty222 if( ptr3[ix3] != NULL ) return EEXIST;223 185 224 186 // register the value 225 187 ptr3[ix3] = value; 188 226 189 hal_fence(); 227 190 … … 246 209 uint32_t ix3 = key & ((1 << w3) - 1); // index in level 3 array 247 210 248 void ** ptr1 = rt->root; // pointer on level 1 array 249 void ** ptr2; // pointer on level 2 array 250 void ** ptr3; // pointer on level 3 array 211 // get ptr1 212 void ** ptr1 = rt->root; 213 214 if( ptr1 == NULL ) return NULL; 251 215 252 216 // get ptr2 253 ptr2 = ptr1[ix1]; 217 void ** ptr2 = ptr1[ix1]; 218 254 219 if( ptr2 == NULL ) return NULL; 255 220 256 221 // get ptr3 257 ptr3 = ptr2[ix2]; 222 void ** ptr3 = ptr2[ix2]; 223 258 224 if( ptr3 == NULL ) return NULL; 259 225 … … 303 269 304 270 } // end grdxt_lookup() 305 306 ////////////////////////////////////////////307 xptr_t grdxt_remote_lookup( xptr_t rt_xp,308 uint32_t key )309 {310 // get cluster and local pointer on remote rt descriptor311 grdxt_t * rt_ptr = GET_PTR( rt_xp );312 cxy_t rt_cxy = GET_CXY( rt_xp );313 314 // get widths315 uint32_t w1 = hal_remote_l32( XPTR( rt_cxy , &rt_ptr->ix1_width ) );316 uint32_t w2 = hal_remote_l32( XPTR( rt_cxy , &rt_ptr->ix2_width ) );317 uint32_t w3 = hal_remote_l32( XPTR( rt_cxy , &rt_ptr->ix3_width ) );318 319 // Check key value320 assert( ((key >> (w1 + w2 + w3)) == 0 ), "illegal key value %x\n", key );321 322 // compute indexes323 uint32_t ix1 = key >> (w2 + w3); // index in level 1 array324 uint32_t ix2 = (key >> w3) & ((1 << w2) -1); // index in level 2 array325 uint32_t ix3 = key & ((1 << w3) - 1); // index in level 3 array326 327 // get ptr1328 void ** ptr1 = hal_remote_lpt( XPTR( rt_cxy , &rt_ptr->root ) );329 330 // get ptr2331 void ** ptr2 = hal_remote_lpt( XPTR( rt_cxy , &ptr1[ix1] ) );332 if( ptr2 == NULL ) return XPTR_NULL;333 334 // get ptr3335 void ** ptr3 = hal_remote_lpt( XPTR( rt_cxy , &ptr2[ix2] ) );336 if( ptr3 == NULL ) return XPTR_NULL;337 338 // get pointer on registered item339 void * item_ptr = hal_remote_lpt( XPTR( rt_cxy , &ptr3[ix3] ) );340 341 // return extended pointer on registered item342 if ( item_ptr == NULL ) return XPTR_NULL;343 else return XPTR( rt_cxy , item_ptr );344 345 } // end grdxt_remote_lookup()346 271 347 272 ////////////////////////////////////// … … 400 325 401 326 } // end grdxt_get_first() 327 328 329 330 //////////////////////////////////////////////////////////////////////////////////////// 331 // Remote access functions 332 //////////////////////////////////////////////////////////////////////////////////////// 333 334 ////////////////////////////////////////////// 335 error_t grdxt_remote_insert( xptr_t rt_xp, 336 uint32_t key, 337 void * value ) 338 { 339 kmem_req_t req; 340 341 // get cluster and local pointer on remote rt descriptor 342 cxy_t rt_cxy = GET_CXY( rt_xp ); 343 grdxt_t * rt_ptr = GET_PTR( rt_xp ); 344 345 // get widths 346 uint32_t w1 = hal_remote_l32( XPTR( rt_cxy , &rt_ptr->ix1_width ) ); 347 uint32_t w2 = hal_remote_l32( XPTR( rt_cxy , &rt_ptr->ix2_width ) ); 348 uint32_t w3 = hal_remote_l32( XPTR( rt_cxy , &rt_ptr->ix3_width ) ); 349 350 // Check key value 351 assert( ((key >> (w1 + w2 + w3)) == 0 ), "illegal key value %x\n", key ); 352 353 // compute indexes 354 uint32_t ix1 = key >> (w2 + w3); // index in level 1 array 355 uint32_t ix2 = (key >> w3) & ((1 << w2) -1); // index in level 2 array 356 uint32_t ix3 = key & ((1 << w3) - 1); // index in level 3 array 357 358 // get ptr1 359 void ** ptr1 = hal_remote_lpt( XPTR( rt_cxy , &rt_ptr->root ) ); 360 361 if( ptr1 == NULL ) return -1; 362 363 // get ptr2 364 void ** ptr2 = hal_remote_lpt( XPTR( rt_cxy , &ptr1[ix1] ) ); 365 366 // allocate memory for the missing level_2 array if required 367 if( ptr2 == NULL ) 368 { 369 // allocate memory in remote cluster 370 req.type = KMEM_KCM; 371 req.order = w2 + ((sizeof(void*) == 4) ? 2 : 3 ); 372 req.flags = AF_ZERO | AF_KERNEL; 373 ptr2 = kmem_remote_alloc( rt_cxy , &req ); 374 375 if( ptr2 == NULL ) return -1; 376 377 // update level_1 entry 378 hal_remote_spt( XPTR( rt_cxy , &ptr1[ix1] ) , ptr2 ); 379 } 380 381 // get ptr3 382 void ** ptr3 = hal_remote_lpt( XPTR( rt_cxy , &ptr2[ix2] ) ); 383 384 // allocate memory for the missing level_3 array if required 385 if( ptr3 == NULL ) 386 { 387 // allocate memory in remote cluster 388 req.type = KMEM_KCM; 389 req.order = w3 + ((sizeof(void*) == 4) ? 2 : 3 ); 390 req.flags = AF_ZERO | AF_KERNEL; 391 ptr3 = kmem_remote_alloc( rt_cxy , &req ); 392 393 if( ptr3 == NULL ) return -1; 394 395 // update level_2 entry 396 hal_remote_spt( XPTR( rt_cxy , &ptr2[ix2] ) , ptr3 ); 397 } 398 399 // register value in level_3 array 400 hal_remote_spt( XPTR( rt_cxy , &ptr3[ix3] ) , value ); 401 402 hal_fence(); 403 404 return 0; 405 406 } // end grdxt_remote_insert() 407 408 //////////////////////////////////////////// 409 void * grdxt_remote_remove( xptr_t rt_xp, 410 uint32_t key ) 411 { 412 // get cluster and local pointer on remote rt descriptor 413 cxy_t rt_cxy = GET_CXY( rt_xp ); 414 grdxt_t * rt_ptr = GET_PTR( rt_xp ); 415 416 // get widths 417 uint32_t w1 = hal_remote_l32( XPTR( rt_cxy , &rt_ptr->ix1_width ) ); 418 uint32_t w2 = hal_remote_l32( XPTR( rt_cxy , &rt_ptr->ix2_width ) ); 419 uint32_t w3 = hal_remote_l32( XPTR( rt_cxy , &rt_ptr->ix3_width ) ); 420 421 // Check key value 422 assert( ((key >> (w1 + w2 + w3)) == 0 ), "illegal key value %x\n", key ); 423 424 // compute indexes 425 uint32_t ix1 = key >> (w2 + w3); // index in level 1 array 426 uint32_t ix2 = (key >> w3) & ((1 << w2) -1); // index in level 2 array 427 uint32_t ix3 = key & ((1 << w3) - 1); // index in level 3 array 428 429 // get ptr1 430 void ** ptr1 = hal_remote_lpt( XPTR( rt_cxy , &rt_ptr->root ) ); 431 432 // get ptr2 433 void ** ptr2 = hal_remote_lpt( XPTR( rt_cxy , &ptr1[ix1] ) ); 434 if( ptr2 == NULL ) return NULL; 435 436 // get ptr3 437 void ** ptr3 = hal_remote_lpt( XPTR( rt_cxy , &ptr2[ix2] ) ); 438 if( ptr3 == NULL ) return NULL; 439 440 // get value 441 void * value = hal_remote_lpt( XPTR( rt_cxy , &ptr3[ix3] ) ); 442 443 // reset selected slot 444 hal_remote_spt( XPTR( rt_cxy, &ptr3[ix3] ) , NULL ); 445 hal_fence(); 446 447 return value; 448 449 } // end grdxt_remote_remove() 450 451 //////////////////////////////////////////// 452 xptr_t grdxt_remote_lookup( xptr_t rt_xp, 453 uint32_t key ) 454 { 455 // get cluster and local pointer on remote rt descriptor 456 grdxt_t * rt_ptr = GET_PTR( rt_xp ); 457 cxy_t rt_cxy = GET_CXY( rt_xp ); 458 459 // get widths 460 uint32_t w1 = hal_remote_l32( XPTR( rt_cxy , &rt_ptr->ix1_width ) ); 461 uint32_t w2 = hal_remote_l32( XPTR( rt_cxy , &rt_ptr->ix2_width ) ); 462 uint32_t w3 = hal_remote_l32( XPTR( rt_cxy , &rt_ptr->ix3_width ) ); 463 464 // Check key value 465 assert( ((key >> (w1 + w2 + w3)) == 0 ), "illegal key value %x\n", key ); 466 467 // compute indexes 468 uint32_t ix1 = key >> (w2 + w3); // index in level 1 array 469 uint32_t ix2 = (key >> w3) & ((1 << w2) -1); // index in level 2 array 470 uint32_t ix3 = key & ((1 << w3) - 1); // index in level 3 array 471 472 // get ptr1 473 void ** ptr1 = hal_remote_lpt( XPTR( rt_cxy , &rt_ptr->root ) ); 474 475 // get ptr2 476 void ** ptr2 = hal_remote_lpt( XPTR( rt_cxy , &ptr1[ix1] ) ); 477 if( ptr2 == NULL ) return XPTR_NULL; 478 479 // get ptr3 480 void ** ptr3 = hal_remote_lpt( XPTR( rt_cxy , &ptr2[ix2] ) ); 481 if( ptr3 == NULL ) return XPTR_NULL; 482 483 // get pointer on registered item 484 void * item_ptr = hal_remote_lpt( XPTR( rt_cxy , &ptr3[ix3] ) ); 485 486 // return extended pointer on registered item 487 if ( item_ptr == NULL ) return XPTR_NULL; 488 else return XPTR( rt_cxy , item_ptr ); 489 490 } // end grdxt_remote_lookup() 491 492 /////////////////////////i///////////////// 493 void grdxt_remote_display( xptr_t rt_xp, 494 char * name ) 495 { 496 uint32_t ix1; 497 uint32_t ix2; 498 uint32_t ix3; 499 500 // check rt_xp 501 assert( (rt_xp != XPTR_NULL) , "pointer on radix tree is NULL\n" ); 502 503 // get cluster and local pointer on remote rt descriptor 504 grdxt_t * rt_ptr = GET_PTR( rt_xp ); 505 cxy_t rt_cxy = GET_CXY( rt_xp ); 506 507 // get widths 508 uint32_t w1 = hal_remote_l32( XPTR( rt_cxy , &rt_ptr->ix1_width ) ); 509 uint32_t w2 = hal_remote_l32( XPTR( rt_cxy , &rt_ptr->ix2_width ) ); 510 uint32_t w3 = hal_remote_l32( XPTR( rt_cxy , &rt_ptr->ix3_width ) ); 511 512 void ** ptr1 = hal_remote_lpt( XPTR( rt_cxy , &rt_ptr->root ) ); 513 514 printk("\n***** Generic Radix Tree for <%s>\n", name ); 515 516 for( ix1=0 ; ix1 < (uint32_t)(1<<w1) ; ix1++ ) 517 { 518 void ** ptr2 = hal_remote_lpt( XPTR( rt_cxy , &ptr1[ix1] ) ); 519 if( ptr2 == NULL ) continue; 520 521 for( ix2=0 ; ix2 < (uint32_t)(1<<w2) ; ix2++ ) 522 { 523 void ** ptr3 = hal_remote_lpt( XPTR( rt_cxy , &ptr2[ix2] ) ); 524 if( ptr3 == NULL ) continue; 525 526 for( ix3=0 ; ix3 < (uint32_t)(1<<w3) ; ix3++ ) 527 { 528 void * value = hal_remote_lpt( XPTR( rt_cxy , &ptr3[ix3] ) ); 529 if( value == NULL ) continue; 530 531 uint32_t key = (ix1<<(w2+w3)) + (ix2<<w3) + ix3; 532 printk(" - key = %x / value = %x\n", key , (intptr_t)value ); 533 } 534 } 535 } 536 537 } // end grdxt_remote_display() 538 539 -
trunk/kernel/libk/grdxt.h
r626 r635 36 36 * Memory for the second and third levels arrays is dynamically allocated by the 37 37 * grdxt_insert() function and is only released by grdxt_destroy(). 38 * - This structure is entirely contained in one single cluster. 39 * - All modifications (insert / remove) must be done by a thread running in local cluster. 40 * - Lookup can be done by a thread running in any cluster (local or remote). 38 * This structure is entirely contained in one single cluster, but to allow any thread 39 * to access it, two sets of access functions are defined: 40 * - local threads can use access function using local pointers. 41 * - remote threads must use the access functions using extended pointers. 41 42 ****************************************************************************************** 42 43 * When it is used by the mapper implementing the file cache: … … 54 55 grdxt_t; 55 56 57 //////////////////////////////////////////////////////////////////////////////////////////// 58 // Local access functions 59 //////////////////////////////////////////////////////////////////////////////////////////// 60 56 61 /******************************************************************************************* 57 62 * This function initialises the radix-tree descriptor, 63 * It must be called by a local thread. 58 64 * and allocates memory for the first level array of pointers. 59 65 ******************************************************************************************* … … 71 77 /******************************************************************************************* 72 78 * This function releases all memory allocated to the radix-tree infrastructure. 73 * The radix-tree is supposed to be empty, but this is NOT checked by this function. 79 * It must be called by a local thread. 80 * A warning message is printed on the kernel TXT0 if the radix tree is not empty. 74 81 ******************************************************************************************* 75 82 * @ rt : pointer on the radix-tree descriptor. … … 79 86 /******************************************************************************************* 80 87 * This function insert a new item in the radix-tree. 88 * It must be called by a local thread. 81 89 * It dynamically allocates memory for new second and third level arrays if required. 82 90 ******************************************************************************************* … … 84 92 * @ key : key value. 85 93 * @ value : pointer on item to be registered in radix-tree. 86 * @ returns 0 if success / returns ENOMEM if no memory, or EINVAL ifillegal key.94 * @ returns 0 if success / returns -1 if no memory, or illegal key. 87 95 ******************************************************************************************/ 88 96 error_t grdxt_insert( grdxt_t * rt, … … 91 99 92 100 /******************************************************************************************* 93 * This function removes an item identified by its key, and returns a pointer 94 * on the removed item. No memory is released. 101 * This function removes an item identified by its key from the radix tree, 102 * It must be called by a local thread. 103 * and returns a pointer on the removed item. No memory is released. 95 104 ******************************************************************************************* 96 105 * @ rt : pointer on the radix-tree descriptor. … … 103 112 /******************************************************************************************* 104 113 * This function returns to a local client, a local pointer on the item identified 114 * It must be called by a local thread. 105 115 * by the <key> argument, from the radix tree identified by the <rt> local pointer. 106 116 ******************************************************************************************* … … 113 123 114 124 /******************************************************************************************* 115 * This function returns to a - possibly remote - remote client, an extended pointer116 * on the item identified by the <key> argument, from the radix tree identified by117 * the <rt_xp> remote pointer.118 *******************************************************************************************119 * @ rt_xp : extended pointer on the radix-tree descriptor.120 * @ key : key value.121 * @ returns an extended pointer on found item if success / returns XPTR_NULL if failure.122 ******************************************************************************************/123 xptr_t grdxt_remote_lookup( xptr_t rt_xp,124 uint32_t key );125 126 /*******************************************************************************************127 125 * This function scan all radix-tree entries in increasing key order, starting from 126 * It must be called by a local thread. 128 127 * the value defined by the <key> argument, and return a pointer on the first valid 129 128 * registered item, and the found item key value. … … 138 137 uint32_t * found_key ); 139 138 139 //////////////////////////////////////////////////////////////////////////////////////////// 140 // Remote access functions 141 //////////////////////////////////////////////////////////////////////////////////////////// 142 143 /******************************************************************************************* 144 * This function insert a new item in a - possibly remote - radix tree. 145 * It dynamically allocates memory for new second and third level arrays if required. 146 ******************************************************************************************* 147 * @ rt_xp : extended pointer on the radix-tree descriptor. 148 * @ key : key value. 149 * @ value : pointer on item to be registered in radix-tree. 150 * @ returns 0 if success / returns -1 if no memory, or illegal key. 151 ******************************************************************************************/ 152 error_t grdxt_remote_insert( xptr_t rt_xp, 153 uint32_t key, 154 void * value ); 155 156 /******************************************************************************************* 157 * This function removes an item identified by its key from a - possibly remote - radix 158 * tree, and returns a local pointer on the removed item. No memory is released. 159 ******************************************************************************************* 160 * @ rt_xp : pointer on the radix-tree descriptor. 161 * @ key : key value. 162 * @ returns local pointer on removed item if success / returns NULL if failure. 163 ******************************************************************************************/ 164 void * grdxt_remote_remove( xptr_t rt_xp, 165 uint32_t key ); 166 167 /******************************************************************************************* 168 * This function returns to a - possibly remote - client, an extended pointer 169 * on the item identified by the <key> argument, from the radix tree identified by 170 * the <rt_xp> remote pointer. 171 ******************************************************************************************* 172 * @ rt_xp : extended pointer on the radix-tree descriptor. 173 * @ key : key value. 174 * @ returns an extended pointer on found item if success / returns XPTR_NULL if failure. 175 ******************************************************************************************/ 176 xptr_t grdxt_remote_lookup( xptr_t rt_xp, 177 uint32_t key ); 178 140 179 /******************************************************************************************* 141 180 * This function displays the current content of a possibly remote radix_tree. … … 144 183 * @ string : radix tree identifier. 145 184 ******************************************************************************************/ 146 void grdxt_display( xptr_t rt_xp, 147 char * string ); 148 185 void grdxt_remote_display( xptr_t rt_xp, 186 char * string ); 149 187 150 188 #endif /* _GRDXT_H_ */ -
trunk/kernel/libk/list.h
r632 r635 304 304 **************************************************************************/ 305 305 306 #define LIST_REMOTE_FIRST( cxy , root , type , member ) 307 ({ list_entry_t * __first = hal_remote_lpt( XPTR( cxy , &root->next ) );\308 LIST_ELEMENT( __first , type , member ); })306 #define LIST_REMOTE_FIRST( cxy , root , type , member ) \ 307 LIST_ELEMENT( hal_remote_lpt( XPTR( (cxy) , &(root)->next ) ), \ 308 type , member ) 309 309 310 310 /*************************************************************************** … … 314 314 * item(s) from the traversed list. 315 315 *************************************************************************** 316 * @ cxy : remote listcluster identifier316 * @ cxy : remote cluster identifier 317 317 * @ root : pointer on the root list_entry 318 318 * @ iter : pointer on the current list_entry -
trunk/kernel/libk/remote_barrier.c
r632 r635 83 83 pthread_barrierattr_t * attr ) 84 84 { 85 xptr_t gen_barrier_xp; // extended pointer on generic barrier descriptor86 85 generic_barrier_t * gen_barrier_ptr; // local pointer on generic barrier descriptor 87 86 void * barrier; // local pointer on implementation barrier descriptor … … 97 96 98 97 // allocate memory for generic barrier descriptor 99 if( ref_cxy == local_cxy ) // reference cluster is local 100 { 101 req.type = KMEM_GEN_BARRIER; 102 req.flags = AF_ZERO; 103 gen_barrier_ptr = kmem_alloc( &req ); 104 gen_barrier_xp = XPTR( local_cxy , gen_barrier_ptr ); 105 } 106 else // reference cluster is remote 107 { 108 rpc_kcm_alloc_client( ref_cxy, 109 KMEM_GEN_BARRIER, 110 &gen_barrier_xp ); 111 gen_barrier_ptr = GET_PTR( gen_barrier_xp ); 112 } 98 req.type = KMEM_KCM; 99 req.order = bits_log2( sizeof(generic_barrier_t) ); 100 req.flags = AF_ZERO | AF_KERNEL; 101 gen_barrier_ptr = kmem_remote_alloc( ref_cxy , &req ); 113 102 114 103 if( gen_barrier_ptr == NULL ) … … 124 113 barrier = simple_barrier_create( count ); 125 114 126 if( barrier == NULL ) 127 { 128 printk("\n[ERROR] in %s : cannot create simple barrier\n", __FUNCTION__); 129 return -1; 130 } 115 if( barrier == NULL ) return -1; 131 116 } 132 117 else // QDT barrier implementation … … 147 132 barrier = dqt_barrier_create( x_size , y_size , nthreads ); 148 133 149 if( barrier == NULL ) 150 { 151 printk("\n[ERROR] in %s : cannot create DQT barrier descriptor\n", __FUNCTION__); 152 return -1; 153 } 134 if( barrier == NULL ) return -1; 154 135 } 155 136 … … 211 192 212 193 // release memory allocated to barrier descriptor 213 if( gen_barrier_cxy == local_cxy ) 214 { 215 req.type = KMEM_GEN_BARRIER; 216 req.ptr = gen_barrier_ptr; 217 kmem_free( &req ); 218 } 219 else 220 { 221 rpc_kcm_free_client( gen_barrier_cxy, 222 gen_barrier_ptr, 223 KMEM_GEN_BARRIER ); 224 } 194 req.type = KMEM_KCM; 195 req.ptr = gen_barrier_ptr; 196 kmem_remote_free( ref_cxy , &req ); 197 225 198 } // end generic_barrier_destroy() 226 199 … … 273 246 simple_barrier_t * simple_barrier_create( uint32_t count ) 274 247 { 275 xptr_t barrier_xp;248 kmem_req_t req; 276 249 simple_barrier_t * barrier; 277 250 … … 285 258 286 259 // allocate memory for simple barrier descriptor 287 if( ref_cxy == local_cxy ) // reference is local 288 { 289 kmem_req_t req; 290 req.type = KMEM_SMP_BARRIER; 291 req.flags = AF_ZERO; 292 barrier = kmem_alloc( &req ); 293 barrier_xp = XPTR( local_cxy , barrier ); 294 } 295 else // reference is remote 296 { 297 rpc_kcm_alloc_client( ref_cxy, 298 KMEM_SMP_BARRIER, 299 &barrier_xp ); 300 barrier = GET_PTR( barrier_xp ); 301 } 302 303 if( barrier == NULL ) return NULL; 260 req.type = KMEM_KCM; 261 req.order = bits_log2( sizeof(simple_barrier_t) ); 262 req.flags = AF_ZERO | AF_KERNEL; 263 barrier = kmem_remote_alloc( ref_cxy , &req ); 264 265 if( barrier == NULL ) 266 { 267 printk("\n[ERROR] in %s : cannot create simple barrier\n", __FUNCTION__ ); 268 return NULL; 269 } 304 270 305 271 // initialise simple barrier descriptor … … 325 291 void simple_barrier_destroy( xptr_t barrier_xp ) 326 292 { 293 kmem_req_t req; 294 327 295 // get barrier cluster and local pointer 328 296 cxy_t barrier_cxy = GET_CXY( barrier_xp ); … … 330 298 331 299 // release memory allocated for barrier descriptor 332 if( barrier_cxy == local_cxy ) 333 { 334 kmem_req_t req; 335 req.type = KMEM_SMP_BARRIER; 336 req.ptr = barrier_ptr; 337 kmem_free( &req ); 338 } 339 else 340 { 341 rpc_kcm_free_client( barrier_cxy, 342 barrier_ptr, 343 KMEM_SMP_BARRIER ); 344 } 300 req.type = KMEM_KCM; 301 req.ptr = barrier_ptr; 302 kmem_remote_free( barrier_cxy , &req ); 345 303 346 304 #if DEBUG_BARRIER_DESTROY … … 498 456 499 457 #if DEBUG_BARRIER_CREATE 500 staticvoid dqt_barrier_display( xptr_t barrier_xp );458 void dqt_barrier_display( xptr_t barrier_xp ); 501 459 #endif 502 460 … … 506 464 uint32_t nthreads ) 507 465 { 508 xptr_t dqt_page_xp;509 page_t * rpc_page;510 xptr_t rpc_page_xp;511 466 dqt_barrier_t * barrier; // local pointer on DQT barrier descriptor 512 467 xptr_t barrier_xp; // extended pointer on DQT barrier descriptor 513 468 uint32_t z; // actual DQT size == max(x_size,y_size) 514 469 uint32_t levels; // actual number of DQT levels 515 xptr_t rpc_xp; // extended pointer on RPC descriptors array516 rpc_desc_t * rpc; // pointer on RPC descriptors array517 uint32_t responses; // responses counter for parallel RPCs518 reg_t save_sr; // for critical section519 470 uint32_t x; // X coordinate in QDT mesh 520 471 uint32_t y; // Y coordinate in QDT mesh … … 522 473 kmem_req_t req; // kmem request 523 474 524 // compute size and number of DQT levels475 // compute number of DQT levels, depending on the mesh size 525 476 z = (x_size > y_size) ? x_size : y_size; 526 477 levels = (z < 2) ? 1 : (z < 3) ? 2 : (z < 5) ? 3 : (z < 9) ? 4 : 5; … … 529 480 assert( (z <= 16) , "DQT mesh size larger than (16*16)\n"); 530 481 531 // check RPC descriptor size532 assert( (sizeof(rpc_desc_t) <= 128), "RPC descriptor larger than 128 bytes\n");533 534 482 // check size of an array of 5 DQT nodes 535 483 assert( (sizeof(dqt_node_t) * 5 <= 512 ), "array of DQT nodes larger than 512 bytes\n"); … … 538 486 assert( (sizeof(dqt_barrier_t) <= 0x4000 ), "DQT barrier descriptor larger than 4 pages\n"); 539 487 540 // get pointer on local client process descriptor488 // get pointer on client thread and process descriptors 541 489 thread_t * this = CURRENT_THREAD; 542 490 process_t * process = this->process; … … 553 501 cxy_t ref_cxy = GET_CXY( ref_xp ); 554 502 555 // 1. allocate 4 4 Kbytes pages for DQT barrier descriptor in reference cluster 556 dqt_page_xp = ppm_remote_alloc_pages( ref_cxy , 2 ); 557 558 if( dqt_page_xp == XPTR_NULL ) return NULL; 559 560 // get pointers on DQT barrier descriptor 561 barrier_xp = ppm_page2base( dqt_page_xp ); 562 barrier = GET_PTR( barrier_xp ); 503 // 1. allocate 4 small pages for the DQT barrier descriptor in reference cluster 504 req.type = KMEM_PPM; 505 req.order = 2; // 4 small pages == 16 Kbytes 506 req.flags = AF_ZERO | AF_KERNEL; 507 barrier = kmem_remote_alloc( ref_cxy , &req ); 508 509 if( barrier == NULL ) 510 { 511 printk("\n[ERROR] in %s : cannot create DQT barrier\n", __FUNCTION__ ); 512 return NULL; 513 } 514 515 // get pointers on DQT barrier descriptor in reference cluster 516 barrier_xp = XPTR( ref_cxy , barrier ); 563 517 564 518 // initialize global parameters in DQT barrier descriptor … … 569 523 #if DEBUG_BARRIER_CREATE 570 524 if( cycle > DEBUG_BARRIER_CREATE ) 571 printk("\n[%s] thread[%x,%x] created DQT barrier descriptor at(%x,%x)\n",525 printk("\n[%s] thread[%x,%x] created DQT barrier descriptor(%x,%x)\n", 572 526 __FUNCTION__, process->pid, this->trdid, ref_cxy, barrier ); 573 527 #endif 574 528 575 // 2. allocate memory from local cluster for an array of 256 RPCs descriptors 576 // cannot share the RPC descriptor, because the returned argument is not shared 577 req.type = KMEM_PAGE; 578 req.size = 3; // 8 pages == 32 Kbytes 579 req.flags = AF_ZERO; 580 rpc_page = kmem_alloc( &req ); 581 rpc_page_xp = XPTR( local_cxy , rpc_page ); 582 583 // get pointers on RPC descriptors array 584 rpc_xp = ppm_page2base( rpc_page_xp ); 585 rpc = GET_PTR( rpc_xp ); 586 587 #if DEBUG_BARRIER_CREATE 588 if( cycle > DEBUG_BARRIER_CREATE ) 589 printk("\n[%s] thread[%x,%x] created RPC descriptors array at (%x,%s)\n", 590 __FUNCTION__, process->pid, this->trdid, local_cxy, rpc ); 591 #endif 592 593 // 3. send parallel RPCs to all existing clusters covered by the DQT 594 // to allocate memory for an array of 5 DQT nodes in each cluster 529 // 2. allocate memory for an array of 5 DQT nodes 530 // in all existing clusters covered by the DQDT 595 531 // (5 nodes per cluster <= 512 bytes per cluster) 596 597 responses = 0; // initialize RPC responses counter 598 599 // mask IRQs 600 hal_disable_irq( &save_sr); 601 602 // client thread blocks itself 603 thread_block( XPTR( local_cxy , this ) , THREAD_BLOCKED_RPC ); 604 532 // and complete barrier descriptor initialisation. 605 533 for ( x = 0 ; x < x_size ; x++ ) 606 534 { 607 535 for ( y = 0 ; y < y_size ; y++ ) 608 536 { 609 // send RPC to existing clusters only 537 cxy_t cxy = HAL_CXY_FROM_XY( x , y ); // target cluster identifier 538 xptr_t local_array_xp; // xptr of nodes array in cluster cxy 539 540 // allocate memory in existing clusters only 610 541 if( LOCAL_CLUSTER->cluster_info[x][y] ) 611 542 { 612 cxy_t cxy = HAL_CXY_FROM_XY( x , y ); // target cluster identifier 613 614 // build a specific RPC descriptor for each target cluster 615 rpc[cxy].rsp = &responses; 616 rpc[cxy].blocking = false; 617 rpc[cxy].index = RPC_KCM_ALLOC; 618 rpc[cxy].thread = this; 619 rpc[cxy].lid = this->core->lid; 620 rpc[cxy].args[0] = (uint64_t)KMEM_512_BYTES; 621 622 // atomically increment expected responses counter 623 hal_atomic_add( &responses , 1 ); 624 625 // send a non-blocking RPC to allocate 512 bytes in target cluster 626 rpc_send( cxy , &rpc[cxy] ); 627 } 628 } 629 } 630 631 #if DEBUG_BARRIER_CREATE 632 if( cycle > DEBUG_BARRIER_CREATE ) 633 printk("\n[%s] thread[%x,%x] sent all RPC requests to allocate dqt_nodes array\n", 634 __FUNCTION__, process->pid, this->trdid ); 635 #endif 636 637 // client thread deschedule 638 sched_yield("blocked on parallel rpc_kcm_alloc"); 639 640 // restore IRQs 641 hal_restore_irq( save_sr); 642 643 // 4. initialize the node_xp[x][y][l] array in DQT barrier descriptor 644 // the node_xp[x][y][0] value is available in rpc.args[1] 645 646 #if DEBUG_BARRIER_CREATE 647 if( cycle > DEBUG_BARRIER_CREATE ) 648 printk("\n[%s] thread[%x,%x] initialises array of pointers on dqt_nodes\n", 649 __FUNCTION__, process->pid, this->trdid ); 650 #endif 651 652 for ( x = 0 ; x < x_size ; x++ ) 653 { 654 for ( y = 0 ; y < y_size ; y++ ) 655 { 656 cxy_t cxy = HAL_CXY_FROM_XY( x , y ); // target cluster identifier 657 xptr_t array_xp = (xptr_t)rpc[cxy].args[1]; // x_pointer on node array 658 uint32_t offset = sizeof( dqt_node_t ); // size of a DQT node 659 660 // set values into the node_xp[x][y][l] array 661 for ( l = 0 ; l < levels ; l++ ) 662 { 663 xptr_t node_xp = array_xp + (offset * l); 664 hal_remote_s64( XPTR( ref_cxy , &barrier->node_xp[x][y][l] ), node_xp ); 665 666 #if DEBUG_BARRIER_CREATE 543 req.type = KMEM_KCM; 544 req.order = 9; // 512 bytes 545 req.flags = AF_ZERO | AF_KERNEL; 546 547 void * ptr = kmem_remote_alloc( cxy , &req ); 548 549 if( ptr == NULL ) 550 { 551 printk("\n[ERROR] in %s : cannot allocate DQT in cluster %x\n", 552 __FUNCTION__, cxy ); 553 return NULL; 554 } 555 556 // build extended pointer on local node array in cluster cxy 557 local_array_xp = XPTR( cxy , ptr ); 558 559 // initialize the node_xp[x][y][l] array in barrier descriptor 560 for ( l = 0 ; l < levels ; l++ ) 561 { 562 xptr_t node_xp = local_array_xp + ( l * sizeof(dqt_node_t) ); 563 hal_remote_s64( XPTR( ref_cxy , &barrier->node_xp[x][y][l] ), node_xp ); 564 565 #if (DEBUG_BARRIER_CREATE & 1) 667 566 if( cycle > DEBUG_BARRIER_CREATE ) 668 567 printk(" - dqt_node_xp[%d,%d,%d] = (%x,%x) / &dqt_node_xp = %x\n", 669 568 x , y , l , GET_CXY( node_xp ), GET_PTR( node_xp ), &barrier->node_xp[x][y][l] ); 670 569 #endif 570 } 671 571 } 672 } 673 } 674 675 // 5. release memory locally allocated for the RPCs array 676 req.type = KMEM_PAGE; 677 req.ptr = rpc_page; 678 kmem_free( &req ); 572 else // register XPTR_NULL for all non-existing entries 573 { 574 for ( l = 0 ; l < levels ; l++ ) 575 { 576 hal_remote_s64( XPTR( ref_cxy , &barrier->node_xp[x][y][l] ), XPTR_NULL ); 577 } 578 } 579 } // end for y 580 } // end for x 679 581 680 582 #if DEBUG_BARRIER_CREATE 681 583 if( cycle > DEBUG_BARRIER_CREATE ) 682 printk("\n[%s] thread[%x,%x] released memory for RPC descriptors array\n",584 printk("\n[%s] thread[%x,%x] initialized array of pointers in DQT barrier\n", 683 585 __FUNCTION__, process->pid, this->trdid ); 684 586 #endif 685 587 686 // 6. initialise all distributed DQT nodes using remote accesses588 // 3. initialise all distributed DQT nodes using remote accesses 687 589 // and the pointers stored in the node_xp[x][y][l] array 688 590 for ( x = 0 ; x < x_size ; x++ ) … … 827 729 void dqt_barrier_destroy( xptr_t barrier_xp ) 828 730 { 829 page_t * rpc_page;830 xptr_t rpc_page_xp;831 rpc_desc_t * rpc; // local pointer on RPC descriptors array832 xptr_t rpc_xp; // extended pointer on RPC descriptor array833 reg_t save_sr; // for critical section834 731 kmem_req_t req; // kmem request 835 836 thread_t * this = CURRENT_THREAD; 732 uint32_t x; 733 uint32_t y; 734 837 735 838 736 // get DQT barrier descriptor cluster and local pointer … … 841 739 842 740 #if DEBUG_BARRIER_DESTROY 741 thread_t * this = CURRENT_THREAD; 843 742 uint32_t cycle = (uint32_t)hal_get_cycles(); 844 743 if( cycle > DEBUG_BARRIER_DESTROY ) … … 851 750 uint32_t y_size = hal_remote_l32( XPTR( barrier_cxy , &barrier_ptr->y_size ) ); 852 751 853 // 1. allocate memory from local cluster for an array of 256 RPCs descriptors 854 // cannot share the RPC descriptor, because the "buf" argument is not shared 855 req.type = KMEM_PAGE; 856 req.size = 3; // 8 pages == 32 Kbytes 857 req.flags = AF_ZERO; 858 rpc_page = kmem_alloc( &req ); 859 rpc_page_xp = XPTR( local_cxy , rpc_page ); 860 861 // get pointers on RPC descriptors array 862 rpc_xp = ppm_page2base( rpc_page_xp ); 863 rpc = GET_PTR( rpc_xp ); 864 865 // 2. send parallel RPCs to all existing clusters covered by the DQT 866 // to release memory allocated for the arrays of DQT nodes in each cluster 867 868 uint32_t responses = 0; // initialize RPC responses counter 869 870 // mask IRQs 871 hal_disable_irq( &save_sr); 872 873 // client thread blocks itself 874 thread_block( XPTR( local_cxy , this ) , THREAD_BLOCKED_RPC ); 875 876 uint32_t x , y; 877 878 #if DEBUG_BARRIER_DESTROY 879 if( cycle > DEBUG_BARRIER_DESTROY ) 880 printk("\n[%s] thread[%x,%x] send RPCs to release the distributed dqt_node array\n", 881 __FUNCTION__, this->process->pid, this->trdid ); 882 #endif 883 752 // 1. release memory allocated for the DQT nodes 753 // in all clusters covered by the QDT mesh 884 754 for ( x = 0 ; x < x_size ; x++ ) 885 755 { 886 756 for ( y = 0 ; y < y_size ; y++ ) 887 757 { 888 // send RPC to existing cluster only 758 // compute target cluster identifier 759 cxy_t cxy = HAL_CXY_FROM_XY( x , y ); 760 761 // existing cluster only 889 762 if( LOCAL_CLUSTER->cluster_info[x][y] ) 890 763 { 891 // compute target cluster identifier892 cxy_t cxy = HAL_CXY_FROM_XY( x , y );893 894 764 // get local pointer on dqt_nodes array in target cluster 895 765 xptr_t buf_xp_xp = XPTR( barrier_cxy , &barrier_ptr->node_xp[x][y][0] ); … … 899 769 assert( (cxy == GET_CXY(buf_xp)) , "bad extended pointer on dqt_nodes array\n" ); 900 770 901 // build a specific RPC descriptor 902 rpc[cxy].rsp = &responses; 903 rpc[cxy].blocking = false; 904 rpc[cxy].index = RPC_KCM_FREE; 905 rpc[cxy].thread = this; 906 rpc[cxy].lid = this->core->lid; 907 rpc[cxy].args[0] = (uint64_t)(intptr_t)buf; 908 rpc[cxy].args[1] = (uint64_t)KMEM_512_BYTES; 909 910 // atomically increment expected responses counter 911 hal_atomic_add( &responses , 1 ); 912 771 req.type = KMEM_KCM; 772 req.ptr = buf; 773 kmem_remote_free( cxy , &req ); 774 913 775 #if DEBUG_BARRIER_DESTROY 776 thread_t * this = CURRENT_THREAD; 777 uint32_t cycle = (uint32_t)hal_get_cycles(); 914 778 if( cycle > DEBUG_BARRIER_DESTROY ) 915 printk(" - target cluster(%d,%d) / buffer %x\n", x, y, buf ); 916 #endif 917 // send a non-blocking RPC to release 512 bytes in target cluster 918 rpc_send( cxy , &rpc[cxy] ); 779 printk("\n[%s] thread[%x,%x] released node array %x in cluster %x / cycle %d\n", 780 __FUNCTION__, this->process->pid, this->trdid, buf, cxy, cycle ); 781 #endif 919 782 } 920 783 } 921 784 } 922 785 923 // client thread deschedule 924 sched_yield("blocked on parallel rpc_kcm_free"); 925 926 // restore IRQs 927 hal_restore_irq( save_sr); 928 929 // 3. release memory locally allocated for the RPC descriptors array 930 req.type = KMEM_PAGE; 931 req.ptr = rpc_page; 932 kmem_free( &req ); 933 934 // 4. release memory allocated for barrier descriptor 935 xptr_t page_xp = ppm_base2page( barrier_xp ); 936 cxy_t page_cxy = GET_CXY( page_xp ); 937 page_t * page_ptr = GET_PTR( page_xp ); 938 939 ppm_remote_free_pages( page_cxy , page_ptr ); 786 // 2. release memory allocated for barrier descriptor in ref cluster 787 req.type = KMEM_PPM; 788 req.ptr = barrier_ptr; 789 kmem_remote_free( barrier_cxy , &req ); 940 790 941 791 #if DEBUG_BARRIER_DESTROY 942 792 cycle = (uint32_t)hal_get_cycles(); 943 793 if( cycle > DEBUG_BARRIER_DESTROY ) 944 printk("\n[%s] thread[%x,%x] exit for barrier (%x,%x) / cycle %d\n",794 printk("\n[%s] thread[%x,%x] release barrier descriptor (%x,%x) / cycle %d\n", 945 795 __FUNCTION__, this->process->pid, this->trdid, barrier_cxy, barrier_ptr, cycle ); 946 796 #endif … … 1022 872 { 1023 873 uint32_t level = hal_remote_l32( XPTR( node_cxy , &node_ptr->level )); 1024 uint32_t arity = hal_remote_l32( XPTR( node_cxy , &node_ptr->arity ));1025 uint32_t count = hal_remote_l32( XPTR( node_cxy , &node_ptr->current ));1026 874 xptr_t pa_xp = hal_remote_l32( XPTR( node_cxy , &node_ptr->parent_xp )); 1027 875 xptr_t c0_xp = hal_remote_l32( XPTR( node_cxy , &node_ptr->child_xp[0] )); … … 1030 878 xptr_t c3_xp = hal_remote_l32( XPTR( node_cxy , &node_ptr->child_xp[3] )); 1031 879 1032 printk(" . level %d : (%x,%x) / %d on %d /P(%x,%x) / C0(%x,%x)"880 printk(" . level %d : (%x,%x) / P(%x,%x) / C0(%x,%x)" 1033 881 " C1(%x,%x) / C2(%x,%x) / C3(%x,%x)\n", 1034 level, node_cxy, node_ptr, count, arity,882 level, node_cxy, node_ptr, 1035 883 GET_CXY(pa_xp), GET_PTR(pa_xp), 1036 884 GET_CXY(c0_xp), GET_PTR(c0_xp), -
trunk/kernel/libk/remote_condvar.c
r581 r635 2 2 * remote_condvar.c - remote kernel condition variable implementation. 3 3 * 4 * Authors Alain Greiner (2016,2017,2018 )4 * Authors Alain Greiner (2016,2017,2018,2019) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 86 86 { 87 87 remote_condvar_t * condvar_ptr; 88 xptr_t condvar_xp;88 kmem_req_t req; 89 89 90 90 // get pointer on local process descriptor … … 98 98 process_t * ref_ptr = (process_t *)GET_PTR( ref_xp ); 99 99 100 // allocate memory for new condvar in reference cluster 101 if( ref_cxy == local_cxy ) // local cluster is the reference 102 { 103 kmem_req_t req; 104 req.type = KMEM_CONDVAR; 105 req.flags = AF_ZERO; 106 condvar_ptr = kmem_alloc( &req ); 107 condvar_xp = XPTR( local_cxy , condvar_ptr ); 108 } 109 else // reference cluster is remote 110 { 111 rpc_kcm_alloc_client( ref_cxy , KMEM_CONDVAR , &condvar_xp ); 112 condvar_ptr = GET_PTR( condvar_xp ); 113 } 114 115 if( condvar_xp == XPTR_NULL ) return 0xFFFFFFFF; 100 req.type = KMEM_KCM; 101 req.order = bits_log2( sizeof(remote_condvar_t) ); 102 req.flags = AF_ZERO | AF_KERNEL; 103 condvar_ptr = kmem_alloc( &req ); 104 105 if( condvar_ptr == NULL ) 106 { 107 printk("\n[ERROR] in %s : cannot create condvar\n", __FUNCTION__ ); 108 return -1; 109 } 116 110 117 111 // initialise condvar … … 136 130 void remote_condvar_destroy( xptr_t condvar_xp ) 137 131 { 132 kmem_req_t req; 133 138 134 // get pointer on local process descriptor 139 135 process_t * process = CURRENT_THREAD->process; … … 166 162 167 163 // release memory allocated for condvar descriptor 168 if( condvar_cxy == local_cxy ) // reference is local 169 { 170 kmem_req_t req; 171 req.type = KMEM_SEM; 172 req.ptr = condvar_ptr; 173 kmem_free( &req ); 174 } 175 else // reference is remote 176 { 177 rpc_kcm_free_client( condvar_cxy , condvar_ptr , KMEM_CONDVAR ); 178 } 164 req.type = KMEM_KCM; 165 req.ptr = condvar_ptr; 166 kmem_remote_free( ref_cxy , &req ); 179 167 180 168 } // end remote_convar_destroy() -
trunk/kernel/libk/remote_condvar.h
r581 r635 2 2 * remote_condvar.h: POSIX condition variable definition. 3 3 * 4 * Authors Alain Greiner (2016,2017,2018 )4 * Authors Alain Greiner (2016,2017,2018,2019) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 78 78 * This function implements the CONVAR_INIT operation. 79 79 * This function creates and initializes a remote_condvar, identified by its virtual 80 * address <vaddr> in the client process reference cluster, using RPC if required.80 * address <vaddr> in the client process reference cluster, using remote access. 81 81 * It registers this user condvar in the reference process descriptor. 82 82 ******************************************************************************************* -
trunk/kernel/libk/remote_mutex.c
r619 r635 2 2 * remote_mutex.c - POSIX mutex implementation. 3 3 * 4 * Authors Alain Greiner (2016,2017,2018 )4 * Authors Alain Greiner (2016,2017,2018,2019) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 84 84 error_t remote_mutex_create( intptr_t ident ) 85 85 { 86 xptr_t mutex_xp;87 86 remote_mutex_t * mutex_ptr; 87 kmem_req_t req; 88 88 89 89 // get pointer on local process descriptor … … 97 97 process_t * ref_ptr = (process_t *)GET_PTR( ref_xp ); 98 98 99 // allocate memory for mutex descriptor 100 if( ref_cxy == local_cxy ) // local cluster is the reference 101 { 102 kmem_req_t req; 103 req.type = KMEM_MUTEX; 104 req.flags = AF_ZERO; 105 mutex_ptr = kmem_alloc( &req ); 106 mutex_xp = XPTR( local_cxy , mutex_ptr ); 107 } 108 else // reference is remote 109 { 110 rpc_kcm_alloc_client( ref_cxy , KMEM_MUTEX , &mutex_xp ); 111 mutex_ptr = GET_PTR( mutex_xp ); 112 } 113 114 if( mutex_ptr == NULL ) return 0xFFFFFFFF; 99 // allocate memory for mutex descriptor in reference cluster 100 req.type = KMEM_KCM; 101 req.order = bits_log2( sizeof(remote_mutex_t) ); 102 req.flags = AF_ZERO | AF_KERNEL; 103 mutex_ptr = kmem_remote_alloc( ref_cxy , &req ); 104 105 if( mutex_ptr == NULL ) 106 { 107 printk("\n[ERROR] in %s : cannot create mutex\n", __FUNCTION__); 108 return -1; 109 } 115 110 116 111 // initialise mutex … … 150 145 void remote_mutex_destroy( xptr_t mutex_xp ) 151 146 { 147 kmem_req_t req; 148 152 149 // get pointer on local process descriptor 153 150 process_t * process = CURRENT_THREAD->process; … … 174 171 175 172 // release memory allocated for mutex descriptor 176 if( mutex_cxy == local_cxy ) // reference is local 177 { 178 kmem_req_t req; 179 req.type = KMEM_MUTEX; 180 req.ptr = mutex_ptr; 181 kmem_free( &req ); 182 } 183 else // reference is remote 184 { 185 rpc_kcm_free_client( mutex_cxy , mutex_ptr , KMEM_MUTEX ); 186 } 173 req.type = KMEM_KCM; 174 req.ptr = mutex_ptr; 175 kmem_remote_free( mutex_cxy , &req ); 187 176 188 177 } // end remote_mutex_destroy() -
trunk/kernel/libk/remote_sem.c
r563 r635 2 2 * remote_sem.c - POSIX unnamed semaphore implementation. 3 3 * 4 * Author Alain Greiner (2016,2017,2018 )4 * Author Alain Greiner (2016,2017,2018,2019) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 86 86 uint32_t value ) 87 87 { 88 kmem_req_t req; 88 89 remote_sem_t * sem_ptr; 89 xptr_t sem_xp;90 90 91 91 // get pointer on local process descriptor … … 100 100 101 101 // allocate memory for new semaphore in reference cluster 102 if( ref_cxy == local_cxy ) // local cluster is the reference 103 { 104 kmem_req_t req; 105 req.type = KMEM_SEM; 106 req.flags = AF_ZERO; 107 sem_ptr = kmem_alloc( &req ); 108 sem_xp = XPTR( local_cxy , sem_ptr ); 102 req.type = KMEM_KCM; 103 req.order = bits_log2( sizeof(remote_sem_t) ); 104 req.flags = AF_ZERO | AF_KERNEL; 105 sem_ptr = kmem_remote_alloc( ref_cxy, &req ); 106 107 if( sem_ptr == NULL ) 108 { 109 printk("\n[ERROR] in %s : cannot create semaphore\n", __FUNCTION__ ); 110 return -1; 109 111 } 110 else // reference is remote111 {112 rpc_kcm_alloc_client( ref_cxy , KMEM_SEM , &sem_xp );113 sem_ptr = GET_PTR( sem_xp );114 }115 116 if( sem_xp == XPTR_NULL ) return 0xFFFFFFFF;117 112 118 113 // initialise semaphore … … 149 144 void remote_sem_destroy( xptr_t sem_xp ) 150 145 { 146 kmem_req_t req; 147 151 148 // get pointer on local process descriptor 152 149 process_t * process = CURRENT_THREAD->process; … … 179 176 180 177 // release memory allocated for semaphore descriptor 181 if( sem_cxy == local_cxy ) // reference is local 182 { 183 kmem_req_t req; 184 req.type = KMEM_SEM; 185 req.ptr = sem_ptr; 186 kmem_free( &req ); 187 } 188 else // reference is remote 189 { 190 rpc_kcm_free_client( sem_cxy , sem_ptr , KMEM_SEM ); 191 } 178 req.type = KMEM_KCM; 179 req.ptr = sem_ptr; 180 kmem_remote_free( sem_cxy , &req ); 192 181 193 182 } // end remote_sem_destroy() -
trunk/kernel/libk/user_dir.c
r633 r635 93 93 uint32_t attr; // attributes for all GPT entries 94 94 uint32_t dirents_per_page; // number of dirent descriptors per page 95 xptr_t page_xp; // extended pointer on page descriptor96 95 page_t * page; // local pointer on page descriptor 97 xptr_t base_xp; // extended pointer on physical page base98 96 struct dirent * base; // local pointer on physical page base 99 97 uint32_t total_dirents; // total number of dirents in dirent array … … 126 124 127 125 // check dirent size 128 assert( ( sizeof(struct dirent) == 64), "sizeof(dirent) !=64\n");126 assert( ( sizeof(struct dirent) == 64), "sizeof(dirent) must be 64\n"); 129 127 130 128 // compute number of dirent per page … … 135 133 136 134 // allocate memory for a local user_dir descriptor 137 req.type = KMEM_DIR; 138 req.flags = AF_ZERO; 135 req.type = KMEM_KCM; 136 req.order = bits_log2( sizeof(user_dir_t) ); 137 req.flags = AF_ZERO | AF_KERNEL; 139 138 dir = kmem_alloc( &req ); 140 139 … … 146 145 } 147 146 148 // Build an initialize the dirent array as a list of p hysical pages.147 // Build an initialize the dirent array as a list of pages. 149 148 // For each iteration in this while loop: 150 149 // - allocate one physical 4 Kbytes (64 dirent slots) … … 163 162 { 164 163 // allocate one physical page 165 req.type = KMEM_P AGE;166 req. size= 0;164 req.type = KMEM_PPM; 165 req.order = 0; 167 166 req.flags = AF_ZERO; 168 page = kmem_alloc( &req );169 170 if( page == NULL )167 base = kmem_alloc( &req ); 168 169 if( base == NULL ) 171 170 { 172 171 printk("\n[ERROR] in %s : cannot allocate page in cluster %x\n", … … 174 173 goto user_dir_create_failure; 175 174 } 176 177 // get pointer on page base (array of dirents)178 page_xp = XPTR( local_cxy , page );179 base_xp = ppm_page2base( page_xp );180 base = GET_PTR( base_xp );181 175 182 176 // call the relevant FS specific function to copy up to 64 dirents in page … … 198 192 total_dirents += entries; 199 193 194 // get page descriptor pointer from base 195 page = GET_PTR( ppm_base2page( XPTR( local_cxy , base ) ) ); 196 200 197 // register page in temporary list 201 198 list_add_last( &root , &page->list ); … … 303 300 304 301 // release the user_dir descriptor 305 req.type = KMEM_ DIR;302 req.type = KMEM_KCM; 306 303 req.ptr = dir; 307 304 kmem_free( &req ); … … 364 361 365 362 // release local user_dir_t structure 366 req.type = KMEM_ DIR;363 req.type = KMEM_KCM; 367 364 req.ptr = dir; 368 365 kmem_free( &req ); … … 372 369 { 373 370 page = LIST_FIRST( &root , page_t , list ); 374 req.type = KMEM_PAGE; 375 req.ptr = page; 371 372 // get base from page descriptor pointer 373 base = GET_PTR( ppm_page2base( XPTR( local_cxy , page ) ) ); 374 375 req.type = KMEM_PPM; 376 req.ptr = base; 376 377 kmem_free( &req ); 377 378 } … … 492 493 // release local user_dir_t structure 493 494 kmem_req_t req; 494 req.type = KMEM_ DIR;495 req.type = KMEM_KCM; 495 496 req.ptr = dir; 496 497 kmem_free( &req ); -
trunk/kernel/libk/user_dir.h
r629 r635 78 78 * This function allocates memory and initializes a user_dir_t structure in the cluster 79 79 * containing the directory inode identified by the <inode> argument and map the 80 * user accessible dirent array in the reference user process V MM, identified by the80 * user accessible dirent array in the reference user process VSL, identified by the 81 81 * <ref_xp> argument. 82 82 * It must be executed by a thread running in the cluster containing the target inode. -
trunk/kernel/libk/xhtab.c
r614 r635 2 2 * xhtab.c - Remote access embedded hash table implementation. 3 3 * 4 * Author Alain Greiner (2016,2017)4 * Author Alain Greiner (2016,2017,2018,2019) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 134 134 uint32_t i; 135 135 136 // initialize readlock136 // initialize lock 137 137 remote_busylock_init( XPTR( local_cxy , &xhtab->lock), LOCK_XHTAB_STATE ); 138 138 … … 153 153 } 154 154 155 for( i=0 ; i < XHASHTAB_SIZE ; i++ ) 156 { 157 xlist_root_init( XPTR( local_cxy , &xhtab->roots[i] ) ); 158 } 159 160 #if DEBUG_XHTAB 161 printk("\n@@@ %s for xhtab (%x,%x)\n" 155 #if DEBUG_XHTAB 156 printk("\n[%s] for xhtab (%x,%x)\n" 162 157 " - index_from_key = %x (@ %x)\n" 163 158 " - item_match_key = %x (@ %x)\n" … … 169 164 #endif 170 165 166 for( i=0 ; i < XHASHTAB_SIZE ; i++ ) 167 { 168 xlist_root_init( XPTR( local_cxy , &xhtab->roots[i] ) ); 169 170 #if (DEBUG_XHTAB & 1) 171 printk("\n - initialize root[%d] / %x\n", i , &xhtab->roots[i] ); 172 #endif 173 174 } 175 171 176 } // end xhtab_init() 172 177 173 ////////////////////////////////////// 174 xptr_t xhtab_scan( xptr_t xhtab_xp, 175 uint32_t index, 176 void * key ) 178 ///////////////////////////////////////////////////////////////////////////////////////////// 179 // This static function traverse the subset identified by the <index> argument 180 // to find an item identified by the <key> argument. 181 ///////////////////////////////////////////////////////////////////////////////////////////// 182 // @ xhtab_xp : extended pointer on the xhtab descriptor. 183 // @ index : subset index. 184 // @ key : searched key value. 185 // @ return extended pointer on the found item if success / return XPTR_NULL if not found. 186 ///////////////////////////////////////////////////////////////////////////////////////////// 187 static xptr_t xhtab_scan( xptr_t xhtab_xp, 188 uint32_t index, 189 void * key ) 177 190 { 178 191 xptr_t xlist_xp; // xlist_entry_t (iterator) … … 220 233 index_from_key_t * index_from_key; // function pointer 221 234 222 #if DEBUG_XHTAB 223 printk("\n[%s] enter / key %s\n", __FUNCTION__, key ); 224 #endif 225 226 // get xhtab cluster and local pointer 227 xhtab_cxy = GET_CXY( xhtab_xp ); 228 xhtab_ptr = GET_PTR( xhtab_xp ); 235 // get xhtab cluster and local pointer 236 xhtab_cxy = GET_CXY( xhtab_xp ); 237 xhtab_ptr = GET_PTR( xhtab_xp ); 238 239 #if DEBUG_XHTAB 240 printk("\n[%s] enter / xhtab (%x,%x) / key = <%s> / cycle %d\n", 241 __FUNCTION__, xhtab_cxy, xhtab_ptr, key, (uint32_t)hal_get_cycles() ); 242 #endif 243 244 // build extended pointer on xhtab lock 245 xptr_t lock_xp = XPTR( xhtab_cxy , &xhtab_ptr->lock ); 229 246 230 247 // get pointer on "index_from_key" function 231 248 index_from_key = (index_from_key_t *)hal_remote_lpt( XPTR( xhtab_cxy , 232 249 &xhtab_ptr->index_from_key ) ); 250 #if DEBUG_XHTAB 251 printk("\n[%s] remote = %x / direct = %x / @ = %x\n", 252 __FUNCTION__, index_from_key, xhtab_ptr->index_from_key, &xhtab_ptr->index_from_key ); 253 #endif 254 233 255 // compute index from key 234 256 index = index_from_key( key ); 235 257 258 #if DEBUG_XHTAB 259 printk("\n[%s] index = %x\n", __FUNCTION__, index ); 260 #endif 261 236 262 // take the lock protecting hash table 237 remote_busylock_acquire( XPTR( xhtab_cxy , &xhtab_ptr->lock ));238 239 // search a matching item 263 remote_busylock_acquire( lock_xp ); 264 265 // search a matching item in subset 240 266 item_xp = xhtab_scan( xhtab_xp , index , key ); 241 267 242 if( item_xp != XPTR_NULL ) // error if found268 if( item_xp != XPTR_NULL ) // error if item already registered 243 269 { 244 270 // release the lock protecting hash table 245 remote_busylock_release( XPTR( xhtab_cxy , &xhtab_ptr->lock ));271 remote_busylock_release( lock_xp ); 246 272 247 273 return -1; … … 256 282 257 283 // release the lock protecting hash table 258 remote_busylock_release( XPTR( xhtab_cxy , &xhtab_ptr->lock ));284 remote_busylock_release( lock_xp ); 259 285 260 286 #if DEBUG_XHTAB 261 printk("\n[%s] success / %s\n", __FUNCTION__, key );287 printk("\n[%s] success / <%s>\n", __FUNCTION__, key ); 262 288 #endif 263 289 -
trunk/kernel/libk/xhtab.h
r614 r635 2 2 * xhtab.h - Remote access embedded hash table definition. 3 3 * 4 * Author Alain Greiner (2016,2017,2018 )4 * Author Alain Greiner (2016,2017,2018,2019) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 38 38 // The main goal is to speedup search by key in a large number of items of same type. 39 39 // For this purpose the set of all registered items is split in several subsets. 40 // Each subset is organised as an embedded double linked xlist s.40 // Each subset is organised as an embedded double linked xlist. 41 41 // - an item is uniquely identified by a <key>, that is a item specific pointer, 42 42 // that can be a - for example - a char* defining the item "name". … … 64 64 65 65 /****************************************************************************************** 66 * This define the four item_type_specific function prototypes that must be defined66 * Here are the four item_type_specific function prototypes that must be defined 67 67 * for each item type. 68 68 *****************************************************************************************/ … … 74 74 75 75 /****************************************************************************************** 76 * This define the supported item types.76 * This define the currently supported item types. 77 77 * - The XHTAB_DENTRY_TYPE is used to implement the set of directory entries for a 78 78 * directory inode : the "children" inode field is an embedded xhtab.
Note: See TracChangeset
for help on using the changeset viewer.