Changeset 632 for trunk/kernel/libk/list.h
- Timestamp:
- May 28, 2019, 2:56:04 PM (5 years ago)
- File:
-
- 1 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_ */
Note: See TracChangeset
for help on using the changeset viewer.