Changeset 632 for trunk/kernel/libk
- Timestamp:
- May 28, 2019, 2:56:04 PM (6 years ago)
- Location:
- trunk/kernel/libk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/libk/list.h
r612 r632 1 1 /* 2 * list.h - Double circular chained lists, inspired from linux2 * list.h - Double circular linked list 3 3 * 4 4 * Authors Ghassan Almaless (2008,2009,2010,2011,2012) 5 * Alain Greiner (2016,2017,2018 )5 * Alain Greiner (2016,2017,2018i,2019) 6 6 * 7 7 * Copyright (c) UPMC Sorbonne Universites … … 28 28 #include <kernel_config.h> 29 29 #include <hal_kernel_types.h> 30 #include <hal_remote.h> 30 31 #include <printk.h> 31 32 … … 34 35 #endif 35 36 37 38 //////////////////////////////////////////////////////////////////////////// 39 // Double circular linked list functions & macros 40 // 41 // It defines a generic local list, as all elements are in the same cluster. 42 // 43 // There is two sets of access functions, because these local lists can be 44 // accessed by local threads, using local pointers, but they can also be 45 // accessed by remote threads running in any cluster, with specific access 46 // functions using extended pointers. 47 //////////////////////////////////////////////////////////////////////////// 48 49 /*************************************************************************** 50 * This structure defines a Double Circular Linked List entry. 51 * Note : The list root is an extra list-entry_t, that is NOT part 52 * of the set of linked elements. 53 **************************************************************************/ 54 55 typedef struct list_entry_s 56 { 57 struct list_entry_s * next; 58 struct list_entry_s * pred; 59 } 60 list_entry_t; 36 61 37 62 /*************************************************************************** … … 46 71 #endif 47 72 48 ////////////////////////////////////////////////////////////////////////////49 ////////////////////////////////////////////////////////////////////////////50 // Double circular linked list functions & macros51 ////////////////////////////////////////////////////////////////////////////52 ////////////////////////////////////////////////////////////////////////////53 54 /***************************************************************************55 * This structure defines a Double Circular Linked List entry.56 * Note : The list root is an extra list-entry_t, that is NOT part57 * of the set of linked elements.58 **************************************************************************/59 60 typedef struct list_entry_s61 {62 struct list_entry_s * next;63 struct list_entry_s * pred;64 }65 list_entry_t;66 67 73 /*************************************************************************** 68 74 * This macro returns a pointer on a structure containing a list_entry_t. … … 77 83 (container_type *)( (char*)__member_ptr - OFFSETOF( container_type , member_name ));}) 78 84 85 86 //////////////////////////////////////////////////////////////////////////// 87 // These functions and macros mus be called by a thread running 88 // in the local cluster to access the local list. 89 //////////////////////////////////////////////////////////////////////////// 90 79 91 /*************************************************************************** 80 92 * This macro returns t pointer on the first element of a list. … … 101 113 /*************************************************************************** 102 114 * This macro traverse a rooted double linked list in forward order. 103 * WARNING : Don't use 2 LIST_FOREACH in the same function, because the104 * variable __ptr will be defined twice, wich result in a compilation error.115 * WARNING : Don't use this macro when you want to remove one or several 116 * item(s) from the traversed list. 105 117 *************************************************************************** 106 118 * @ root : pointer on the root list_entry … … 149 161 150 162 /*************************************************************************** 151 * This function inserts a new entry in first place of a double linked list. 163 * This function must be called by a thread running in local cluster. 164 * It inserts a new entry in first place of a double linked list. 152 165 *************************************************************************** 153 166 * @ root : pointer on the list root … … 157 170 list_entry_t * entry ) 158 171 { 159 list_entry_t * pred_entry; 160 list_entry_t * next_entry; 161 162 pred_entry = root; 163 next_entry = root->next; 164 165 entry->next = next_entry; 166 entry->pred = pred_entry; 167 168 pred_entry->next = entry; 169 next_entry->pred = entry; 170 } 171 172 /*************************************************************************** 173 * This function inserts a new entry in last place of a double linked list. 172 list_entry_t * next = root->next; 173 174 entry->next = next; 175 entry->pred = root; 176 177 root->next = entry; 178 next->pred = entry; 179 } 180 181 /*************************************************************************** 182 * This function must be called by a thread running in local cluster. 183 * It inserts a new entry in last place of a double linked list. 174 184 *************************************************************************** 175 185 * @ root : pointer on the list root … … 179 189 list_entry_t * entry ) 180 190 { 181 list_entry_t * pred_entry; 182 list_entry_t * next_entry; 183 184 pred_entry = root->pred; 185 next_entry = root; 186 187 entry->next = next_entry; 188 entry->pred = pred_entry; 189 190 pred_entry->next = entry; 191 next_entry->pred = entry; 192 } 193 194 /*************************************************************************** 195 * This function returns true if the list is empty. 191 list_entry_t * pred = root->pred; 192 193 entry->next = root; 194 entry->pred = pred; 195 196 root->pred = entry; 197 pred->next = entry; 198 } 199 200 /*************************************************************************** 201 * This function must be called by a thread running in local cluster. 202 * It returns true if the list is empty. 196 203 *************************************************************************** 197 204 * @ root : pointer on the list root … … 202 209 } 203 210 204 /*************************************************************************** 205 * This function remove an entry from a rooted double linked list. 211 212 /*************************************************************************** 213 * This function must be called by a thread running in local cluster. 214 * It removes an entry from the list. 206 215 *************************************************************************** 207 216 * @ entry : pointer on the entry to be removed. … … 209 218 static inline void list_unlink( list_entry_t * entry ) 210 219 { 211 list_entry_t * pred _entry;212 list_entry_t * next _entry;213 214 pred _entry= entry->pred;215 next _entry= entry->next;216 217 pred _entry->next = entry->next;218 next _entry->pred = entry->pred;220 list_entry_t * pred; 221 list_entry_t * next; 222 223 pred = entry->pred; 224 next = entry->next; 225 226 pred->next = next; 227 next->pred = pred; 219 228 } 220 229 … … 278 287 279 288 289 290 //////////////////////////////////////////////////////////////////////////// 291 // These functions and macros can be used by any thread running 292 // in any cluster to access a remote local list. 293 //////////////////////////////////////////////////////////////////////////// 294 295 /*************************************************************************** 296 * This macro can be used by a thread running in any cluster to access 297 * a remote local list. It returns a local pointer on the first element 298 * of the remote list in the remote cluster. 299 *************************************************************************** 300 * @ cxy : remote list cluster identifier 301 * @ root : local pointer on the list root 302 * @ type : type of the linked element 303 * @ member : name of the list_entry_t field 304 **************************************************************************/ 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 ); }) 309 310 /*************************************************************************** 311 * This macro can be used by a thread running in any cluster to access 312 * a remote local list. It traverse the list in forward order. 313 * WARNING : Don't use this macro when you want to remove one or several 314 * item(s) from the traversed list. 315 *************************************************************************** 316 * @ cxy : remote list cluster identifier 317 * @ root : pointer on the root list_entry 318 * @ iter : pointer on the current list_entry 319 **************************************************************************/ 320 321 #define LIST_REMOTE_FOREACH( cxy , root , iter ) \ 322 for( (iter) = hal_remote_lpt( XPTR( cxy , &(root)->next ) ) ; \ 323 (iter) != (root) ; \ 324 (iter) = hal_remote_lpt( XPTR( cxy , &(iter)->next ) ) ) 325 326 /*************************************************************************** 327 * This function can be called by a thread running in any cluster to access 328 * a remote local list. It returns true if the list is empty. 329 *************************************************************************** 330 * @ cxy : remote list cluster identifier 331 * @ root : local pointer on the remote list root 332 **************************************************************************/ 333 static inline bool_t list_remote_is_empty( cxy_t cxy, 334 list_entry_t * root ) 335 { 336 list_entry_t * next = hal_remote_lpt( XPTR( cxy , &root->next ) ); 337 return( root == next ); 338 } 339 340 /*************************************************************************** 341 * This function can be called by a thread running in any cluster to access 342 * a remote local list. It inserts a new entry in first place of the list. 343 *************************************************************************** 344 * @ cxy : remote list cluster identifier 345 * @ root : local pointer on the remote list root 346 * @ entry : local pointer on the remote entry to be inserted 347 **************************************************************************/ 348 static inline void list_remote_add_first( cxy_t cxy, 349 list_entry_t * root, 350 list_entry_t * entry ) 351 { 352 list_entry_t * first; // local pointer on current first entry 353 list_entry_t * next; // local pointer on current first->next entry 354 355 first = hal_remote_lpt( XPTR( cxy , &root->next ) ); 356 next = hal_remote_lpt( XPTR( cxy , &first->next ) ); 357 358 hal_remote_spt( XPTR( cxy , &entry->next ) , first ); 359 hal_remote_spt( XPTR( cxy , &entry->pred ) , root ); 360 361 hal_remote_spt( XPTR( cxy , &root->next ) , entry ); 362 hal_remote_spt( XPTR( cxy , &next->pred ) , entry ); 363 } 364 365 /*************************************************************************** 366 * This function can be called by a thread running in any cluster to access 367 * a remote local list. It inserts a new entry in last place of the list. 368 *************************************************************************** 369 * @ cxy : remote list cluster identifier 370 * @ root : local pointer on the remote list root 371 * @ entry : local pointer on the remote entry to be inserted 372 **************************************************************************/ 373 static inline void list_remote_add_last( cxy_t cxy, 374 list_entry_t * root, 375 list_entry_t * entry ) 376 { 377 list_entry_t * last; // local pointer on current last entry 378 list_entry_t * pred; // local pointer on current last->pred entry 379 380 last = hal_remote_lpt( XPTR( cxy , &root->pred ) ); 381 pred = hal_remote_lpt( XPTR( cxy , &last->pred ) ); 382 383 hal_remote_spt( XPTR( cxy , &entry->next ) , root ); 384 hal_remote_spt( XPTR( cxy , &entry->pred ) , pred ); 385 386 hal_remote_spt( XPTR( cxy , &root->pred ) , entry ); 387 hal_remote_spt( XPTR( cxy , &pred->next ) , entry ); 388 } 389 390 /*************************************************************************** 391 * This function can be called by a thread running in any cluster to access 392 * a remote local list. It removes an entry from the list. 393 *************************************************************************** 394 * @ cxy : remote list cluster identifier 395 * @ entry : pointer on the entry to be removed. 396 **************************************************************************/ 397 static inline void list_remote_unlink( cxy_t cxy, 398 list_entry_t * entry ) 399 { 400 list_entry_t * pred; 401 list_entry_t * next; 402 403 pred = hal_remote_lpt( XPTR( cxy , &entry->pred ) ); 404 next = hal_remote_lpt( XPTR( cxy , &entry->next ) ); 405 406 hal_remote_spt( XPTR( cxy , &pred->next ) , next ); 407 hal_remote_spt( XPTR( cxy , &next->pred ) , pred ); 408 } 409 410 411 280 412 #endif /* _LIST_H_ */ -
trunk/kernel/libk/remote_barrier.c
r629 r632 506 506 uint32_t nthreads ) 507 507 { 508 page_t * dqt_page;509 508 xptr_t dqt_page_xp; 510 509 page_t * rpc_page; … … 514 513 uint32_t z; // actual DQT size == max(x_size,y_size) 515 514 uint32_t levels; // actual number of DQT levels 516 kmem_req_t req; // kmem request517 515 xptr_t rpc_xp; // extended pointer on RPC descriptors array 518 516 rpc_desc_t * rpc; // pointer on RPC descriptors array … … 522 520 uint32_t y; // Y coordinate in QDT mesh 523 521 uint32_t l; // level coordinate 522 kmem_req_t req; // kmem request 524 523 525 524 // compute size and number of DQT levels … … 554 553 cxy_t ref_cxy = GET_CXY( ref_xp ); 555 554 556 // 1. allocate memory for DQT barrier descriptor in reference cluster 557 if( ref_cxy == local_cxy ) 558 { 559 req.type = KMEM_PAGE; 560 req.size = 2; // 4 pages == 16 Kbytes 561 req.flags = AF_ZERO; 562 dqt_page = kmem_alloc( &req ); 563 dqt_page_xp = XPTR( local_cxy , dqt_page ); 564 } 565 else 566 { 567 rpc_pmem_get_pages_client( ref_cxy, 568 2, 569 &dqt_page ); 570 dqt_page_xp = XPTR( ref_cxy , dqt_page ); 571 } 572 573 if( dqt_page == NULL ) return NULL; 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; 574 559 575 560 // get pointers on DQT barrier descriptor … … 948 933 949 934 // 4. release memory allocated for barrier descriptor 950 xptr_t page_xp = ppm_base2page( barrier_xp ); 951 page_t * page = GET_PTR( page_xp ); 952 953 if( barrier_cxy == local_cxy ) 954 { 955 req.type = KMEM_PAGE; 956 req.ptr = page; 957 kmem_free( &req ); 958 } 959 else 960 { 961 rpc_pmem_release_pages_client( barrier_cxy, 962 page ); 963 } 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 ); 964 940 965 941 #if DEBUG_BARRIER_DESTROY
Note: See TracChangeset
for help on using the changeset viewer.