Changeset 4fded58 in mainline


Ignore:
Timestamp:
2006-05-31T12:33:30Z (19 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
76d7305
Parents:
3de6dd7a
Message:

Reference counting for futexes.

Location:
generic
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • generic/include/proc/task.h

    r3de6dd7a r4fded58  
    3232#include <typedefs.h>
    3333#include <synch/spinlock.h>
     34#include <synch/mutex.h>
    3435#include <adt/btree.h>
    3536#include <adt/list.h>
     
    5455       
    5556        task_arch_t arch;       /**< Architecture specific task data. */
     57       
     58        /**
     59          * Serializes access to the B+tree of task's futexes. This mutex is
     60          * independent on the task spinlock.
     61          */
     62        mutex_t futexes_lock;
     63        btree_t futexes;        /**< B+tree of futexes referenced by this task. */
    5664};
    5765
  • generic/include/synch/futex.h

    r3de6dd7a r4fded58  
    4141        waitq_t wq;             /**< Wait queue for threads waiting for futex availability. */
    4242        link_t ht_link;         /**< Futex hash table link. */
     43        count_t refcount;       /**< Number of tasks that reference this futex. */
    4344};
    4445
  • generic/src/proc/task.c

    r3de6dd7a r4fded58  
    103103                ipc_phone_connect(&ta->phones[0], ipc_phone_0);
    104104        atomic_set(&ta->active_calls, 0);
     105
     106        mutex_initialize(&ta->futexes_lock);
     107        btree_create(&ta->futexes);
    105108       
    106109        ipl = interrupts_disable();
  • generic/src/synch/futex.c

    r3de6dd7a r4fded58  
    3030 * @file        futex.c
    3131 * @brief       Kernel backend for futexes.
    32  *
    33  * @todo Deallocation of orphaned kernel-side futex structures is not currently implemented.
    3432 */
    3533
     
    4240#include <mm/slab.h>
    4341#include <proc/thread.h>
     42#include <proc/task.h>
    4443#include <genarch/mm/page_pt.h>
    4544#include <genarch/mm/page_ht.h>
     
    6160static void futex_ht_remove_callback(link_t *item);
    6261
    63 /** Read-write lock protecting global futex hash table. */
     62/**
     63 * Read-write lock protecting global futex hash table.
     64 * It is also used to serialize access to all futex_t structures.
     65 * Must be acquired before the task futex B+tree lock.
     66 */
    6467static rwlock_t futex_ht_lock;
    6568
     
    9093        link_initialize(&futex->ht_link);
    9194        futex->paddr = 0;
     95        futex->refcount = 1;
    9296}
    9397
     
    169173/** Find kernel address of the futex structure corresponding to paddr.
    170174 *
    171  * If the structure does not exist alreay, a new one is created.
     175 * If the structure does not exist already, a new one is created.
    172176 *
    173177 * @param paddr Physical address of the userspace futex counter.
     
    179183        link_t *item;
    180184        futex_t *futex;
     185        btree_node_t *leaf;
    181186       
    182187        /*
     
    188193        if (item) {
    189194                futex = hash_table_get_instance(item, futex_t, ht_link);
     195
     196                /*
     197                 * See if the current task knows this futex.
     198                 */
     199                mutex_lock(&TASK->futexes_lock);
     200                if (!btree_search(&TASK->futexes, paddr, &leaf)) {
     201                        /*
     202                         * The futex is new to the current task.
     203                         * However, we only have read access.
     204                         * Gain write access and try again.
     205                         */
     206                        mutex_unlock(&TASK->futexes_lock);
     207                        goto gain_write_access;
     208                }
     209                mutex_unlock(&TASK->futexes_lock);
     210
    190211                rwlock_read_unlock(&futex_ht_lock);
    191212        } else {
     213gain_write_access:
    192214                /*
    193215                 * Upgrade to writer is not currently supported,
     
    205227                if (item) {
    206228                        futex = hash_table_get_instance(item, futex_t, ht_link);
     229                       
     230                        /*
     231                         * See if this futex is known to the current task.
     232                         */
     233                        mutex_lock(&TASK->futexes_lock);
     234                        if (!btree_search(&TASK->futexes, paddr, &leaf)) {
     235                                /*
     236                                 * The futex is new to the current task.
     237                                 * Upgrade its reference count and put it to the
     238                                 * current task's B+tree of known futexes.
     239                                 */
     240                                futex->refcount++;
     241                                btree_insert(&TASK->futexes, paddr, futex, leaf);
     242                        }
     243                        mutex_unlock(&TASK->futexes_lock);
     244       
    207245                        rwlock_write_unlock(&futex_ht_lock);
    208246                } else {
     
    211249                        futex->paddr = paddr;
    212250                        hash_table_insert(&futex_ht, &paddr, &futex->ht_link);
     251                       
     252                        /*
     253                         * This is the first task referencing the futex.
     254                         * It can be directly inserted into its
     255                         * B+tree of known futexes.
     256                         */
     257                        mutex_lock(&TASK->futexes_lock);
     258                        btree_insert(&TASK->futexes, paddr, futex, NULL);
     259                        mutex_unlock(&TASK->futexes_lock);
     260                       
    213261                        rwlock_write_unlock(&futex_ht_lock);
    214262                }
Note: See TracChangeset for help on using the changeset viewer.