Changeset ee42e43 in mainline for kernel/generic/src/synch/futex.c
- Timestamp:
- 2010-06-22T11:29:40Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- a49a1a1
- Parents:
- fdaad75d
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/synch/futex.c
rfdaad75d ree42e43 37 37 38 38 #include <synch/futex.h> 39 #include <synch/ rwlock.h>39 #include <synch/mutex.h> 40 40 #include <synch/spinlock.h> 41 41 #include <synch/synch.h> … … 65 65 66 66 /** 67 * Read-write lockprotecting global futex hash table.67 * Mutex protecting global futex hash table. 68 68 * It is also used to serialize access to all futex_t structures. 69 69 * Must be acquired before the task futex B+tree lock. 70 70 */ 71 static rwlock_t futex_ht_lock;71 static mutex_t futex_ht_lock; 72 72 73 73 /** Futex hash table. */ … … 84 84 void futex_init(void) 85 85 { 86 rwlock_initialize(&futex_ht_lock);86 mutex_initialize(&futex_ht_lock, MUTEX_PASSIVE); 87 87 hash_table_create(&futex_ht, FUTEX_HT_SIZE, 1, &futex_ht_ops); 88 88 } … … 194 194 * or allocate new one if it does not exist already. 195 195 */ 196 rwlock_read_lock(&futex_ht_lock);196 mutex_lock(&futex_ht_lock); 197 197 item = hash_table_find(&futex_ht, &paddr); 198 198 if (item) { … … 206 206 /* 207 207 * The futex is new to the current task. 208 * However, we only have read access.209 * Gain write access and try again.208 * Upgrade its reference count and put it to the 209 * current task's B+tree of known futexes. 210 210 */ 211 mutex_unlock(&TASK->futexes_lock);212 goto gain_write_access;211 futex->refcount++; 212 btree_insert(&TASK->futexes, paddr, futex, leaf); 213 213 } 214 214 mutex_unlock(&TASK->futexes_lock); 215 216 rwlock_read_unlock(&futex_ht_lock);217 215 } else { 218 gain_write_access: 216 futex = (futex_t *) malloc(sizeof(futex_t), 0); 217 futex_initialize(futex); 218 futex->paddr = paddr; 219 hash_table_insert(&futex_ht, &paddr, &futex->ht_link); 220 219 221 /* 220 * Upgrade to writer is not currently supported,221 * therefore, it is necessary to release the read lock222 * and reacquire it as a writer.222 * This is the first task referencing the futex. 223 * It can be directly inserted into its 224 * B+tree of known futexes. 223 225 */ 224 rwlock_read_unlock(&futex_ht_lock); 225 226 rwlock_write_lock(&futex_ht_lock); 227 /* 228 * Avoid possible race condition by searching 229 * the hash table once again with write access. 230 */ 231 item = hash_table_find(&futex_ht, &paddr); 232 if (item) { 233 futex = hash_table_get_instance(item, futex_t, ht_link); 234 235 /* 236 * See if this futex is known to the current task. 237 */ 238 mutex_lock(&TASK->futexes_lock); 239 if (!btree_search(&TASK->futexes, paddr, &leaf)) { 240 /* 241 * The futex is new to the current task. 242 * Upgrade its reference count and put it to the 243 * current task's B+tree of known futexes. 244 */ 245 futex->refcount++; 246 btree_insert(&TASK->futexes, paddr, futex, 247 leaf); 248 } 249 mutex_unlock(&TASK->futexes_lock); 250 251 rwlock_write_unlock(&futex_ht_lock); 252 } else { 253 futex = (futex_t *) malloc(sizeof(futex_t), 0); 254 futex_initialize(futex); 255 futex->paddr = paddr; 256 hash_table_insert(&futex_ht, &paddr, &futex->ht_link); 257 258 /* 259 * This is the first task referencing the futex. 260 * It can be directly inserted into its 261 * B+tree of known futexes. 262 */ 263 mutex_lock(&TASK->futexes_lock); 264 btree_insert(&TASK->futexes, paddr, futex, NULL); 265 mutex_unlock(&TASK->futexes_lock); 266 267 rwlock_write_unlock(&futex_ht_lock); 268 } 226 mutex_lock(&TASK->futexes_lock); 227 btree_insert(&TASK->futexes, paddr, futex, NULL); 228 mutex_unlock(&TASK->futexes_lock); 229 269 230 } 231 mutex_unlock(&futex_ht_lock); 270 232 271 233 return futex; … … 318 280 link_t *cur; 319 281 320 rwlock_write_lock(&futex_ht_lock);282 mutex_lock(&futex_ht_lock); 321 283 mutex_lock(&TASK->futexes_lock); 322 284 … … 338 300 339 301 mutex_unlock(&TASK->futexes_lock); 340 rwlock_write_unlock(&futex_ht_lock);302 mutex_unlock(&futex_ht_lock); 341 303 } 342 304
Note:
See TracChangeset
for help on using the changeset viewer.