Changeset 3ac5086 in mainline


Ignore:
Timestamp:
2012-11-24T02:08:55Z (11 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.

Location:
kernel/generic
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/include/adt/cht.h

    rd04e46e r3ac5086  
    136136        size_t max_load, bool can_block, cht_ops_t *op);
    137137extern void cht_destroy(cht_t *h);
     138extern void cht_destroy_unsafe(cht_t *h);
    138139
    139140extern cht_link_t *cht_find(cht_t *h, void *key);
  • kernel/generic/include/proc/task.h

    rd04e46e r3ac5086  
    129129        task_arch_t arch;
    130130       
    131         /** Serializes access to futex_list (independent of the task spinlock). */
    132         mutex_t futex_list_lock;
    133         /** List of all futexes accesses by this task. */
    134         list_t futex_list;
    135         /** CHT mapping virtual addresses of futex variables to futex objects. */
    136131        struct futex_cache {
     132                /** CHT mapping virtual addresses of futex variables to futex objects.*/
     133                cht_t ht;
     134                /** Serializes access to futex_list.*/
     135                mutex_t list_lock;
     136                /** List of all futexes accesses by this task. */
     137                list_t list;
    137138                work_t destroy_work;
    138                 cht_t ht;
    139139        } *futexes;
    140140       
  • kernel/generic/src/adt/cht.c

    rd04e46e r3ac5086  
    617617void cht_destroy(cht_t *h)
    618618{
     619        cht_destroy_unsafe(h);
     620       
     621        /* You must clear the table of items. Otherwise cht_destroy will leak. */
     622        ASSERT(atomic_get(&h->item_cnt) == 0);
     623}
     624
     625/** Destroys a successfully created CHT but does no error checking. */
     626void cht_destroy_unsafe(cht_t *h)
     627{
    619628        /* Wait for resize to complete. */
    620629        while (0 < atomic_get(&h->resize_reqs)) {
     
    627636        free(h->b);
    628637        h->b = NULL;
    629        
    630         /* You must clear the table of items. Otherwise cht_destroy will leak. */
    631         ASSERT(atomic_get(&h->item_cnt) == 0);
    632638}
    633639
  • kernel/generic/src/proc/task.c

    rd04e46e r3ac5086  
    165165        spinlock_initialize(&task->active_calls_lock, "active_calls_lock");
    166166        list_initialize(&task->active_calls);
    167        
    168         mutex_initialize(&task->futex_list_lock, MUTEX_PASSIVE);
    169         list_initialize(&task->futex_list);
    170        
     167               
    171168#ifdef CONFIG_UDEBUG
    172169        /* Init kbox stuff */
  • 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.