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