Changes in uspace/lib/c/generic/fibril_synch.c [84b7384:9414abc] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/fibril_synch.c
r84b7384 r9414abc 58 58 } 59 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;69 }70 71 60 static void print_deadlock(fibril_owner_info_t *oi) 72 61 { … … 89 78 oi = oi->owned_by->waits_for; 90 79 } 91 92 abort(); 93 } 80 } 81 82 83 static void check_for_deadlock(fibril_owner_info_t *oi) 84 { 85 while (oi && oi->owned_by) { 86 if (oi->owned_by == (fibril_t *) fibril_get_id()) { 87 print_deadlock(oi); 88 abort(); 89 } 90 oi = oi->owned_by->waits_for; 91 } 92 } 93 94 94 95 95 void fibril_mutex_initialize(fibril_mutex_t *fm) … … 113 113 link_initialize(&wdata.wu_event.link); 114 114 list_append(&wdata.wu_event.link, &fm->waiters); 115 116 if (check_for_deadlock(&fm->oi)) 117 print_deadlock(&fm->oi); 115 check_for_deadlock(&fm->oi); 118 116 f->waits_for = &fm->oi; 119 120 117 fibril_switch(FIBRIL_TO_MANAGER); 121 118 } else { … … 183 180 void fibril_rwlock_read_lock(fibril_rwlock_t *frw) 184 181 { 182 fibril_t *f = (fibril_t *) fibril_get_id(); 183 185 184 futex_down(&async_futex); 186 185 if (frw->writers) { 187 fibril_t *f = (fibril_t *) fibril_get_id();188 186 awaiter_t wdata; 189 187 … … 194 192 f->flags &= ~FIBRIL_WRITER; 195 193 list_append(&wdata.wu_event.link, &frw->waiters); 194 check_for_deadlock(&frw->oi); 195 f->waits_for = &frw->oi; 196 196 fibril_switch(FIBRIL_TO_MANAGER); 197 197 } else { 198 frw->readers++; 198 /* Consider the first reader the owner. */ 199 if (frw->readers++ == 0) 200 frw->oi.owned_by = f; 199 201 futex_up(&async_futex); 200 202 } … … 203 205 void fibril_rwlock_write_lock(fibril_rwlock_t *frw) 204 206 { 207 fibril_t *f = (fibril_t *) fibril_get_id(); 208 205 209 futex_down(&async_futex); 206 210 if (frw->writers || frw->readers) { 207 fibril_t *f = (fibril_t *) fibril_get_id();208 211 awaiter_t wdata; 209 212 … … 214 217 f->flags |= FIBRIL_WRITER; 215 218 list_append(&wdata.wu_event.link, &frw->waiters); 219 check_for_deadlock(&frw->oi); 220 f->waits_for = &frw->oi; 216 221 fibril_switch(FIBRIL_TO_MANAGER); 217 222 } else { 223 frw->oi.owned_by = f; 218 224 frw->writers++; 219 225 futex_up(&async_futex); … … 226 232 assert(frw->readers || (frw->writers == 1)); 227 233 if (frw->readers) { 228 if (--frw->readers) 234 if (--frw->readers) { 235 if (frw->oi.owned_by == (fibril_t *) fibril_get_id()) { 236 /* 237 * If this reader firbril was considered the 238 * owner of this rwlock, clear the ownership 239 * information even if there are still more 240 * readers. 241 * 242 * This is the limitation of the detection 243 * mechanism rooted in the fact that tracking 244 * all readers would require dynamically 245 * allocated memory for keeping linkage info. 246 */ 247 frw->oi.owned_by = NULL; 248 } 229 249 goto out; 250 } 230 251 } else { 231 252 frw->writers--; … … 233 254 234 255 assert(!frw->readers && !frw->writers); 256 257 frw->oi.owned_by = NULL; 235 258 236 259 while (!list_empty(&frw->waiters)) { … … 241 264 wdp = list_get_instance(tmp, awaiter_t, wu_event.link); 242 265 f = (fibril_t *) wdp->fid; 266 267 f->waits_for = NULL; 243 268 244 269 if (f->flags & FIBRIL_WRITER) { … … 250 275 fibril_add_ready(wdp->fid); 251 276 frw->writers++; 277 frw->oi.owned_by = f; 252 278 optimize_execution_power(); 253 279 break; … … 257 283 list_remove(&wdp->wu_event.link); 258 284 fibril_add_ready(wdp->fid); 259 frw->readers++; 285 if (frw->readers++ == 0) { 286 /* Consider the first reader the owner. */ 287 frw->oi.owned_by = f; 288 } 260 289 optimize_execution_power(); 261 290 }
Note:
See TracChangeset
for help on using the changeset viewer.