Changeset 4fded58 in mainline for generic/src/synch/futex.c
- Timestamp:
- 2006-05-31T12:33:30Z (19 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 76d7305
- Parents:
- 3de6dd7a
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
generic/src/synch/futex.c
r3de6dd7a r4fded58 30 30 * @file futex.c 31 31 * @brief Kernel backend for futexes. 32 *33 * @todo Deallocation of orphaned kernel-side futex structures is not currently implemented.34 32 */ 35 33 … … 42 40 #include <mm/slab.h> 43 41 #include <proc/thread.h> 42 #include <proc/task.h> 44 43 #include <genarch/mm/page_pt.h> 45 44 #include <genarch/mm/page_ht.h> … … 61 60 static void futex_ht_remove_callback(link_t *item); 62 61 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 */ 64 67 static rwlock_t futex_ht_lock; 65 68 … … 90 93 link_initialize(&futex->ht_link); 91 94 futex->paddr = 0; 95 futex->refcount = 1; 92 96 } 93 97 … … 169 173 /** Find kernel address of the futex structure corresponding to paddr. 170 174 * 171 * If the structure does not exist alrea y, a new one is created.175 * If the structure does not exist already, a new one is created. 172 176 * 173 177 * @param paddr Physical address of the userspace futex counter. … … 179 183 link_t *item; 180 184 futex_t *futex; 185 btree_node_t *leaf; 181 186 182 187 /* … … 188 193 if (item) { 189 194 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 190 211 rwlock_read_unlock(&futex_ht_lock); 191 212 } else { 213 gain_write_access: 192 214 /* 193 215 * Upgrade to writer is not currently supported, … … 205 227 if (item) { 206 228 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 207 245 rwlock_write_unlock(&futex_ht_lock); 208 246 } else { … … 211 249 futex->paddr = paddr; 212 250 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 213 261 rwlock_write_unlock(&futex_ht_lock); 214 262 }
Note:
See TracChangeset
for help on using the changeset viewer.