Changes in kernel/generic/src/synch/futex.c [4774a32:a49a1a1] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/synch/futex.c
r4774a32 ra49a1a1 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 } … … 113 113 uintptr_t paddr; 114 114 pte_t *t; 115 ipl_t ipl;116 115 int rc; 117 116 118 ipl = interrupts_disable();119 120 117 /* 121 118 * Find physical address of futex counter. … … 125 122 if (!t || !PTE_VALID(t) || !PTE_PRESENT(t)) { 126 123 page_table_unlock(AS, true); 127 interrupts_restore(ipl);128 124 return (unative_t) ENOENT; 129 125 } … … 131 127 page_table_unlock(AS, true); 132 128 133 interrupts_restore(ipl);134 135 129 futex = futex_find(paddr); 136 130 … … 156 150 uintptr_t paddr; 157 151 pte_t *t; 158 ipl_t ipl;159 160 ipl = interrupts_disable();161 152 162 153 /* … … 167 158 if (!t || !PTE_VALID(t) || !PTE_PRESENT(t)) { 168 159 page_table_unlock(AS, true); 169 interrupts_restore(ipl);170 160 return (unative_t) ENOENT; 171 161 } … … 173 163 page_table_unlock(AS, true); 174 164 175 interrupts_restore(ipl);176 177 165 futex = futex_find(paddr); 178 166 … … 200 188 * or allocate new one if it does not exist already. 201 189 */ 202 rwlock_read_lock(&futex_ht_lock);190 mutex_lock(&futex_ht_lock); 203 191 item = hash_table_find(&futex_ht, &paddr); 204 192 if (item) { … … 212 200 /* 213 201 * The futex is new to the current task. 214 * However, we only have read access.215 * Gain write access and try again.202 * Upgrade its reference count and put it to the 203 * current task's B+tree of known futexes. 216 204 */ 217 mutex_unlock(&TASK->futexes_lock);218 goto gain_write_access;205 futex->refcount++; 206 btree_insert(&TASK->futexes, paddr, futex, leaf); 219 207 } 220 208 mutex_unlock(&TASK->futexes_lock); 221 222 rwlock_read_unlock(&futex_ht_lock);223 209 } else { 224 gain_write_access: 210 futex = (futex_t *) malloc(sizeof(futex_t), 0); 211 futex_initialize(futex); 212 futex->paddr = paddr; 213 hash_table_insert(&futex_ht, &paddr, &futex->ht_link); 214 225 215 /* 226 * Upgrade to writer is not currently supported,227 * therefore, it is necessary to release the read lock228 * and reacquire it as a writer.216 * This is the first task referencing the futex. 217 * It can be directly inserted into its 218 * B+tree of known futexes. 229 219 */ 230 rwlock_read_unlock(&futex_ht_lock); 231 232 rwlock_write_lock(&futex_ht_lock); 233 /* 234 * Avoid possible race condition by searching 235 * the hash table once again with write access. 236 */ 237 item = hash_table_find(&futex_ht, &paddr); 238 if (item) { 239 futex = hash_table_get_instance(item, futex_t, ht_link); 240 241 /* 242 * See if this futex is known to the current task. 243 */ 244 mutex_lock(&TASK->futexes_lock); 245 if (!btree_search(&TASK->futexes, paddr, &leaf)) { 246 /* 247 * The futex is new to the current task. 248 * Upgrade its reference count and put it to the 249 * current task's B+tree of known futexes. 250 */ 251 futex->refcount++; 252 btree_insert(&TASK->futexes, paddr, futex, 253 leaf); 254 } 255 mutex_unlock(&TASK->futexes_lock); 256 257 rwlock_write_unlock(&futex_ht_lock); 258 } else { 259 futex = (futex_t *) malloc(sizeof(futex_t), 0); 260 futex_initialize(futex); 261 futex->paddr = paddr; 262 hash_table_insert(&futex_ht, &paddr, &futex->ht_link); 263 264 /* 265 * This is the first task referencing the futex. 266 * It can be directly inserted into its 267 * B+tree of known futexes. 268 */ 269 mutex_lock(&TASK->futexes_lock); 270 btree_insert(&TASK->futexes, paddr, futex, NULL); 271 mutex_unlock(&TASK->futexes_lock); 272 273 rwlock_write_unlock(&futex_ht_lock); 274 } 220 mutex_lock(&TASK->futexes_lock); 221 btree_insert(&TASK->futexes, paddr, futex, NULL); 222 mutex_unlock(&TASK->futexes_lock); 223 275 224 } 225 mutex_unlock(&futex_ht_lock); 276 226 277 227 return futex; … … 324 274 link_t *cur; 325 275 326 rwlock_write_lock(&futex_ht_lock);276 mutex_lock(&futex_ht_lock); 327 277 mutex_lock(&TASK->futexes_lock); 328 278 … … 344 294 345 295 mutex_unlock(&TASK->futexes_lock); 346 rwlock_write_unlock(&futex_ht_lock);296 mutex_unlock(&futex_ht_lock); 347 297 } 348 298
Note:
See TracChangeset
for help on using the changeset viewer.