Changeset 3ac5086 in mainline for kernel/generic/src/synch/futex.c


Ignore:
Timestamp:
2012-11-24T02:08:55Z (12 years ago)
Author:
Adam Hraska <adam.hraska+hos@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
5d230a30
Parents:
d04e46e
Message:

Fixed kernel futex cleanup: now walks list via correct links and frees items once it is sure cht is not resizing.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/synch/futex.c

    rd04e46e r3ac5086  
    158158       
    159159        cht_create(&task->futexes->ht, 0, 0, 0, true, &task_futex_ht_ops);
     160       
     161        list_initialize(&task->futexes->list);
     162        mutex_initialize(&task->futexes->list_lock, MUTEX_PASSIVE);
    160163}
    161164
    162165/** Destroys the futex structures for the dying task. */
    163 void futex_task_deinit(struct task *task)
     166void futex_task_deinit(task_t *task)
    164167{
    165168        /* Interrupts are disabled so we must not block (cannot run cht_destroy). */
     
    180183                member_to_inst(work, struct futex_cache, destroy_work);
    181184       
    182         cht_destroy(&cache->ht);
     185        /*
     186         * Destroy the cache before manually freeing items of the cache in case
     187         * table resize is in progress.
     188         */
     189        cht_destroy_unsafe(&cache->ht);
     190       
     191        /* Manually free futex_ptr cache items. */
     192        list_foreach_safe(cache->list, cur_link, next_link) {
     193                futex_ptr_t *fut_ptr = member_to_inst(cur_link, futex_ptr_t, all_link);
     194
     195                list_remove(cur_link);
     196                free(fut_ptr);
     197        }
     198       
    183199        free(cache);
    184200}
     
    187203void futex_task_cleanup(void)
    188204{
     205        struct futex_cache *futexes = TASK->futexes;
     206       
    189207        /* All threads of this task have terminated. This is the last thread. */
    190         mutex_lock(&TASK->futex_list_lock);
    191        
    192         list_foreach_safe(TASK->futex_list, cur_link, next_link) {
    193                 futex_ptr_t *fut_ptr = member_to_inst(cur_link, futex_ptr_t, cht_link);
    194                
     208        mutex_lock(&futexes->list_lock);
     209       
     210        list_foreach_safe(futexes->list, cur_link, next_link) {
     211                futex_ptr_t *fut_ptr = member_to_inst(cur_link, futex_ptr_t, all_link);
     212
    195213                /*
    196214                 * The function is free to free the futex. All other threads of this
     
    202220                 */
    203221                futex_release_ref_locked(fut_ptr->futex);
    204                
    205                 /*
    206                  * No need to remove the futex_ptr from the CHT cache of this task
    207                  * because futex_task_deinit() will destroy the CHT shortly.
    208                  */
    209                 list_remove(cur_link);
    210                 free(fut_ptr);
    211         }
    212        
    213         mutex_unlock(&TASK->futex_list_lock);
     222        }
     223       
     224        mutex_unlock(&futexes->list_lock);
    214225}
    215226
     
    355366        /* Cache the mapping from the virtual address to the futex for this task. */
    356367        if (cht_insert_unique(&TASK->futexes->ht, &fut_ptr->cht_link, &dup_link)) {
    357                 mutex_lock(&TASK->futex_list_lock);
    358                 list_append(&fut_ptr->all_link, &TASK->futex_list);
    359                 mutex_unlock(&TASK->futex_list_lock);
     368                mutex_lock(&TASK->futexes->list_lock);
     369                list_append(&fut_ptr->all_link, &TASK->futexes->list);
     370                mutex_unlock(&TASK->futexes->list_lock);
    360371        } else {
    361372                /* Another thread of this task beat us to it. Use that mapping instead.*/
Note: See TracChangeset for help on using the changeset viewer.