Changes in uspace/lib/c/generic/fibril_synch.c [d161715:84b7384] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/fibril_synch.c
rd161715 r84b7384 36 36 #include <fibril.h> 37 37 #include <async.h> 38 #include <async_priv.h> 38 39 #include <adt/list.h> 39 40 #include <futex.h> … … 43 44 #include <stacktrace.h> 44 45 #include <stdlib.h> 45 #include <stdio.h>46 #include "private/async.h"47 46 48 47 static void optimize_execution_power(void) … … 56 55 */ 57 56 if (atomic_get(&threads_in_ipc_wait) > 0) 58 async_poke(); 57 ipc_poke(); 58 } 59 60 static bool check_for_deadlock(fibril_owner_info_t *oi) 61 { 62 while (oi && oi->owned_by) { 63 if (oi->owned_by == (fibril_t *) fibril_get_id()) 64 return true; 65 oi = oi->owned_by->waits_for; 66 } 67 68 return false; 59 69 } 60 70 … … 79 89 oi = oi->owned_by->waits_for; 80 90 } 81 } 82 83 84 static void check_for_deadlock(fibril_owner_info_t *oi) 85 { 86 while (oi && oi->owned_by) { 87 if (oi->owned_by == (fibril_t *) fibril_get_id()) { 88 print_deadlock(oi); 89 abort(); 90 } 91 oi = oi->owned_by->waits_for; 92 } 93 } 94 91 92 abort(); 93 } 95 94 96 95 void fibril_mutex_initialize(fibril_mutex_t *fm) … … 104 103 { 105 104 fibril_t *f = (fibril_t *) fibril_get_id(); 106 107 if (fibril_get_sercount() != 0)108 abort();109 105 110 106 futex_down(&async_futex); … … 117 113 link_initialize(&wdata.wu_event.link); 118 114 list_append(&wdata.wu_event.link, &fm->waiters); 119 check_for_deadlock(&fm->oi); 115 116 if (check_for_deadlock(&fm->oi)) 117 print_deadlock(&fm->oi); 120 118 f->waits_for = &fm->oi; 119 121 120 fibril_switch(FIBRIL_TO_MANAGER); 122 121 } else { … … 143 142 static void _fibril_mutex_unlock_unsafe(fibril_mutex_t *fm) 144 143 { 144 assert(fm->counter <= 0); 145 145 if (fm->counter++ < 0) { 146 146 link_t *tmp; … … 168 168 void fibril_mutex_unlock(fibril_mutex_t *fm) 169 169 { 170 assert(fibril_mutex_is_locked(fm));171 170 futex_down(&async_futex); 172 171 _fibril_mutex_unlock_unsafe(fm); 173 172 futex_up(&async_futex); 174 }175 176 bool fibril_mutex_is_locked(fibril_mutex_t *fm)177 {178 bool locked = false;179 180 futex_down(&async_futex);181 if (fm->counter <= 0)182 locked = true;183 futex_up(&async_futex);184 185 return locked;186 173 } 187 174 … … 196 183 void fibril_rwlock_read_lock(fibril_rwlock_t *frw) 197 184 { 198 fibril_t *f = (fibril_t *) fibril_get_id();199 200 if (fibril_get_sercount() != 0)201 abort();202 203 185 futex_down(&async_futex); 204 186 if (frw->writers) { 187 fibril_t *f = (fibril_t *) fibril_get_id(); 205 188 awaiter_t wdata; 206 189 … … 211 194 f->flags &= ~FIBRIL_WRITER; 212 195 list_append(&wdata.wu_event.link, &frw->waiters); 213 check_for_deadlock(&frw->oi);214 f->waits_for = &frw->oi;215 196 fibril_switch(FIBRIL_TO_MANAGER); 216 197 } else { 217 /* Consider the first reader the owner. */ 218 if (frw->readers++ == 0) 219 frw->oi.owned_by = f; 198 frw->readers++; 220 199 futex_up(&async_futex); 221 200 } … … 224 203 void fibril_rwlock_write_lock(fibril_rwlock_t *frw) 225 204 { 226 fibril_t *f = (fibril_t *) fibril_get_id();227 228 if (fibril_get_sercount() != 0)229 abort();230 231 205 futex_down(&async_futex); 232 206 if (frw->writers || frw->readers) { 207 fibril_t *f = (fibril_t *) fibril_get_id(); 233 208 awaiter_t wdata; 234 209 … … 239 214 f->flags |= FIBRIL_WRITER; 240 215 list_append(&wdata.wu_event.link, &frw->waiters); 241 check_for_deadlock(&frw->oi);242 f->waits_for = &frw->oi;243 216 fibril_switch(FIBRIL_TO_MANAGER); 244 217 } else { 245 frw->oi.owned_by = f;246 218 frw->writers++; 247 219 futex_up(&async_futex); … … 252 224 { 253 225 futex_down(&async_futex); 226 assert(frw->readers || (frw->writers == 1)); 254 227 if (frw->readers) { 255 if (--frw->readers) { 256 if (frw->oi.owned_by == (fibril_t *) fibril_get_id()) { 257 /* 258 * If this reader firbril was considered the 259 * owner of this rwlock, clear the ownership 260 * information even if there are still more 261 * readers. 262 * 263 * This is the limitation of the detection 264 * mechanism rooted in the fact that tracking 265 * all readers would require dynamically 266 * allocated memory for keeping linkage info. 267 */ 268 frw->oi.owned_by = NULL; 269 } 228 if (--frw->readers) 270 229 goto out; 271 }272 230 } else { 273 231 frw->writers--; … … 275 233 276 234 assert(!frw->readers && !frw->writers); 277 278 frw->oi.owned_by = NULL;279 235 280 236 while (!list_empty(&frw->waiters)) { … … 285 241 wdp = list_get_instance(tmp, awaiter_t, wu_event.link); 286 242 f = (fibril_t *) wdp->fid; 287 288 f->waits_for = NULL;289 243 290 244 if (f->flags & FIBRIL_WRITER) { … … 296 250 fibril_add_ready(wdp->fid); 297 251 frw->writers++; 298 frw->oi.owned_by = f;299 252 optimize_execution_power(); 300 253 break; … … 304 257 list_remove(&wdp->wu_event.link); 305 258 fibril_add_ready(wdp->fid); 306 if (frw->readers++ == 0) { 307 /* Consider the first reader the owner. */ 308 frw->oi.owned_by = f; 309 } 259 frw->readers++; 310 260 optimize_execution_power(); 311 261 } … … 317 267 void fibril_rwlock_read_unlock(fibril_rwlock_t *frw) 318 268 { 319 assert(fibril_rwlock_is_read_locked(frw));320 269 _fibril_rwlock_common_unlock(frw); 321 270 } … … 323 272 void fibril_rwlock_write_unlock(fibril_rwlock_t *frw) 324 273 { 325 assert(fibril_rwlock_is_write_locked(frw));326 274 _fibril_rwlock_common_unlock(frw); 327 }328 329 bool fibril_rwlock_is_read_locked(fibril_rwlock_t *frw)330 {331 bool locked = false;332 333 futex_down(&async_futex);334 if (frw->readers)335 locked = true;336 futex_up(&async_futex);337 338 return locked;339 }340 341 bool fibril_rwlock_is_write_locked(fibril_rwlock_t *frw)342 {343 bool locked = false;344 345 futex_down(&async_futex);346 if (frw->writers) {347 assert(frw->writers == 1);348 locked = true;349 }350 futex_up(&async_futex);351 352 return locked;353 }354 355 bool fibril_rwlock_is_locked(fibril_rwlock_t *frw)356 {357 return fibril_rwlock_is_read_locked(frw) ||358 fibril_rwlock_is_write_locked(frw);359 275 } 360 276 … … 369 285 { 370 286 awaiter_t wdata; 371 372 assert(fibril_mutex_is_locked(fm));373 287 374 288 if (timeout < 0)
Note:
See TracChangeset
for help on using the changeset viewer.