Changeset 1b20da0 in mainline for kernel/generic/src/synch/futex.c
- Timestamp:
- 2018-02-28T17:52:03Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 3061bc1
- Parents:
- df6ded8
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-02-28 17:26:03)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-02-28 17:52:03)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/synch/futex.c
rdf6ded8 r1b20da0 35 35 * @file 36 36 * @brief Kernel backend for futexes. 37 * 38 * Kernel futex objects are stored in a global hash table futex_ht 37 * 38 * Kernel futex objects are stored in a global hash table futex_ht 39 39 * where the physical address of the futex variable (futex_t.paddr) 40 * is used as the lookup key. As a result multiple address spaces 41 * may share the same futex variable. 42 * 40 * is used as the lookup key. As a result multiple address spaces 41 * may share the same futex variable. 42 * 43 43 * A kernel futex object is created the first time a task accesses 44 * the futex (having a futex variable at a physical address not 44 * the futex (having a futex variable at a physical address not 45 45 * encountered before). Futex object's lifetime is governed by 46 46 * a reference count that represents the number of all the different … … 48 48 * physical address of the futex variable. A futex object is freed 49 49 * when the last task having accessed the futex exits. 50 * 50 * 51 51 * Each task keeps track of the futex objects it accessed in a list 52 * of pointers (futex_ptr_t, task->futex_list) to the different futex 52 * of pointers (futex_ptr_t, task->futex_list) to the different futex 53 53 * objects. 54 * 54 * 55 55 * To speed up translation of futex variables' virtual addresses 56 56 * to their physical addresses, futex pointers accessed by the 57 57 * task are furthermore stored in a concurrent hash table (CHT, 58 58 * task->futexes->ht). A single lookup without locks or accesses 59 * to the page table translates a futex variable's virtual address 60 * into its futex kernel object. 59 * to the page table translates a futex variable's virtual address 60 * into its futex kernel object. 61 61 */ 62 62 … … 119 119 120 120 /** Mutex protecting the global futex hash table. 121 * 121 * 122 122 * Acquire task specific TASK->futex_list_lock before this mutex. 123 123 */ … … 125 125 126 126 /** Global kernel futex hash table. Lock futex_ht_lock before accessing. 127 * 127 * 128 128 * Physical address of the futex variable is the lookup key. 129 129 */ … … 170 170 if (interrupts_disabled()) { 171 171 /* Invoke the blocking cht_destroy in the background. */ 172 workq_global_enqueue_noblock(&task->futexes->destroy_work, 172 workq_global_enqueue_noblock(&task->futexes->destroy_work, 173 173 destroy_task_cache); 174 174 } else { … … 181 181 static void destroy_task_cache(work_t *work) 182 182 { 183 struct futex_cache *cache = 183 struct futex_cache *cache = 184 184 member_to_inst(work, struct futex_cache, destroy_work); 185 185 186 /* 186 /* 187 187 * Destroy the cache before manually freeing items of the cache in case 188 188 * table resize is in progress. … … 216 216 * task have already terminated, so they have also definitely 217 217 * exited their CHT futex cache protecting rcu reader sections. 218 * Moreover release_ref() only frees the futex if this is the 218 * Moreover release_ref() only frees the futex if this is the 219 219 * last task referencing the futex. Therefore, only threads 220 220 * of this task may have referenced the futex if it is to be freed. … … 273 273 futex_t *futex = find_cached_futex(uaddr); 274 274 275 if (futex) 275 if (futex) 276 276 return futex; 277 277 … … 319 319 320 320 if (futex_ptr_link) { 321 futex_ptr_t *futex_ptr 321 futex_ptr_t *futex_ptr 322 322 = member_to_inst(futex_ptr_link, futex_ptr_t, cht_link); 323 323 … … 333 333 334 334 335 /** 336 * Returns a kernel futex for the physical address @a phys_addr and caches 335 /** 336 * Returns a kernel futex for the physical address @a phys_addr and caches 337 337 * it in this task under the virtual address @a uaddr (if not already cached). 338 338 */ … … 341 341 futex_t *futex = malloc(sizeof(futex_t), 0); 342 342 343 /* 344 * Find the futex object in the global futex table (or insert it 343 /* 344 * Find the futex object in the global futex table (or insert it 345 345 * if it is not present). 346 346 */ … … 360 360 spinlock_unlock(&futex_ht_lock); 361 361 362 /* 363 * Cache the link to the futex object for this task. 362 /* 363 * Cache the link to the futex object for this task. 364 364 */ 365 365 futex_ptr_t *fut_ptr = malloc(sizeof(futex_ptr_t), 0); … … 382 382 383 383 futex_ptr_t *dup = member_to_inst(dup_link, futex_ptr_t, cht_link); 384 futex = dup->futex; 384 futex = dup->futex; 385 385 } 386 386 … … 402 402 futex_t *futex = get_futex(uaddr); 403 403 404 if (!futex) 404 if (!futex) 405 405 return (sys_errno_t) ENOENT; 406 406 … … 473 473 474 474 /* 475 * Operations of a task's CHT that caches mappings of futex user space 475 * Operations of a task's CHT that caches mappings of futex user space 476 476 * virtual addresses to kernel futex objects. 477 477 */
Note:
See TracChangeset
for help on using the changeset viewer.