Changes in uspace/lib/c/generic/fibril_synch.c [9414abc:63f8966] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/fibril_synch.c
r9414abc r63f8966 42 42 #include <errno.h> 43 43 #include <assert.h> 44 #include <stacktrace.h>45 #include <stdlib.h>46 44 47 45 static void optimize_execution_power(void) … … 58 56 } 59 57 60 static void print_deadlock(fibril_owner_info_t *oi)61 {62 fibril_t *f = (fibril_t *) fibril_get_id();63 64 printf("Deadlock detected.\n");65 stacktrace_print();66 67 printf("Fibril %p waits for primitive %p.\n", f, oi);68 69 while (oi && oi->owned_by) {70 printf("Primitive %p is owned by fibril %p.\n",71 oi, oi->owned_by);72 if (oi->owned_by == f)73 break;74 stacktrace_print_fp_pc(context_get_fp(&oi->owned_by->ctx),75 oi->owned_by->ctx.pc);76 printf("Fibril %p waits for primitive %p.\n",77 oi->owned_by, oi->owned_by->waits_for);78 oi = oi->owned_by->waits_for;79 }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 95 58 void fibril_mutex_initialize(fibril_mutex_t *fm) 96 59 { 97 fm->oi.owned_by = NULL;98 60 fm->counter = 1; 99 61 list_initialize(&fm->waiters); … … 102 64 void fibril_mutex_lock(fibril_mutex_t *fm) 103 65 { 104 fibril_t *f = (fibril_t *) fibril_get_id();105 106 66 futex_down(&async_futex); 107 67 if (fm->counter-- <= 0) { … … 113 73 link_initialize(&wdata.wu_event.link); 114 74 list_append(&wdata.wu_event.link, &fm->waiters); 115 check_for_deadlock(&fm->oi);116 f->waits_for = &fm->oi;117 75 fibril_switch(FIBRIL_TO_MANAGER); 118 76 } else { 119 fm->oi.owned_by = f;120 77 futex_up(&async_futex); 121 78 } … … 129 86 if (fm->counter > 0) { 130 87 fm->counter--; 131 fm->oi.owned_by = (fibril_t *) fibril_get_id();132 88 locked = true; 133 89 } … … 143 99 link_t *tmp; 144 100 awaiter_t *wdp; 145 fibril_t *f;146 101 147 102 assert(!list_empty(&fm->waiters)); … … 150 105 wdp->active = true; 151 106 wdp->wu_event.inlist = false; 152 153 f = (fibril_t *) wdp->fid;154 fm->oi.owned_by = f;155 f->waits_for = NULL;156 157 107 list_remove(&wdp->wu_event.link); 158 108 fibril_add_ready(wdp->fid); 159 109 optimize_execution_power(); 160 } else {161 fm->oi.owned_by = NULL;162 110 } 163 111 } … … 172 120 void fibril_rwlock_initialize(fibril_rwlock_t *frw) 173 121 { 174 frw->oi.owned_by = NULL;175 122 frw->writers = 0; 176 123 frw->readers = 0; … … 180 127 void fibril_rwlock_read_lock(fibril_rwlock_t *frw) 181 128 { 182 fibril_t *f = (fibril_t *) fibril_get_id();183 184 129 futex_down(&async_futex); 185 130 if (frw->writers) { 131 fibril_t *f = (fibril_t *) fibril_get_id(); 186 132 awaiter_t wdata; 187 133 … … 192 138 f->flags &= ~FIBRIL_WRITER; 193 139 list_append(&wdata.wu_event.link, &frw->waiters); 194 check_for_deadlock(&frw->oi);195 f->waits_for = &frw->oi;196 140 fibril_switch(FIBRIL_TO_MANAGER); 197 141 } else { 198 /* Consider the first reader the owner. */ 199 if (frw->readers++ == 0) 200 frw->oi.owned_by = f; 142 frw->readers++; 201 143 futex_up(&async_futex); 202 144 } … … 205 147 void fibril_rwlock_write_lock(fibril_rwlock_t *frw) 206 148 { 207 fibril_t *f = (fibril_t *) fibril_get_id();208 209 149 futex_down(&async_futex); 210 150 if (frw->writers || frw->readers) { 151 fibril_t *f = (fibril_t *) fibril_get_id(); 211 152 awaiter_t wdata; 212 153 … … 217 158 f->flags |= FIBRIL_WRITER; 218 159 list_append(&wdata.wu_event.link, &frw->waiters); 219 check_for_deadlock(&frw->oi);220 f->waits_for = &frw->oi;221 160 fibril_switch(FIBRIL_TO_MANAGER); 222 161 } else { 223 frw->oi.owned_by = f;224 162 frw->writers++; 225 163 futex_up(&async_futex); … … 232 170 assert(frw->readers || (frw->writers == 1)); 233 171 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 } 172 if (--frw->readers) 249 173 goto out; 250 }251 174 } else { 252 175 frw->writers--; … … 254 177 255 178 assert(!frw->readers && !frw->writers); 256 257 frw->oi.owned_by = NULL;258 179 259 180 while (!list_empty(&frw->waiters)) { … … 264 185 wdp = list_get_instance(tmp, awaiter_t, wu_event.link); 265 186 f = (fibril_t *) wdp->fid; 266 267 f->waits_for = NULL;268 187 269 188 if (f->flags & FIBRIL_WRITER) { … … 275 194 fibril_add_ready(wdp->fid); 276 195 frw->writers++; 277 frw->oi.owned_by = f;278 196 optimize_execution_power(); 279 197 break; … … 283 201 list_remove(&wdp->wu_event.link); 284 202 fibril_add_ready(wdp->fid); 285 if (frw->readers++ == 0) { 286 /* Consider the first reader the owner. */ 287 frw->oi.owned_by = f; 288 } 203 frw->readers++; 289 204 optimize_execution_power(); 290 205 }
Note:
See TracChangeset
for help on using the changeset viewer.