Changeset 985e26d2 in mainline for uspace/lib/libc/generic/fibril_synch.c
- Timestamp:
- 2010-01-07T19:06:59Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 8190e63
- Parents:
- 743e17b (diff), eca2435 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/libc/generic/fibril_synch.c
r743e17b r985e26d2 33 33 */ 34 34 35 #include <fibril_sync .h>35 #include <fibril_synch.h> 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> 41 #include <sys/time.h> 42 #include <errno.h> 40 43 #include <assert.h> 41 44 … … 63 66 futex_down(&async_futex); 64 67 if (fm->counter-- <= 0) { 65 fibril_t *f = (fibril_t *) fibril_get_id(); 66 list_append(&f->link, &fm->waiters); 68 awaiter_t wdata; 69 70 wdata.fid = fibril_get_id(); 71 wdata.active = false; 72 wdata.wu_event.inlist = true; 73 link_initialize(&wdata.wu_event.link); 74 list_append(&wdata.wu_event.link, &fm->waiters); 67 75 fibril_switch(FIBRIL_TO_MANAGER); 68 76 } else { … … 90 98 if (fm->counter++ < 0) { 91 99 link_t *tmp; 92 fibril_t *f;100 awaiter_t *wdp; 93 101 94 102 assert(!list_empty(&fm->waiters)); 95 103 tmp = fm->waiters.next; 96 f = list_get_instance(tmp, fibril_t, link); 97 list_remove(&f->link); 98 fibril_add_ready((fid_t) f); 104 wdp = list_get_instance(tmp, awaiter_t, wu_event.link); 105 wdp->active = true; 106 wdp->wu_event.inlist = false; 107 list_remove(&wdp->wu_event.link); 108 fibril_add_ready(wdp->fid); 99 109 optimize_execution_power(); 100 110 } … … 120 130 if (frw->writers) { 121 131 fibril_t *f = (fibril_t *) fibril_get_id(); 132 awaiter_t wdata; 133 134 wdata.fid = (fid_t) f; 135 wdata.active = false; 136 wdata.wu_event.inlist = true; 137 link_initialize(&wdata.wu_event.link); 122 138 f->flags &= ~FIBRIL_WRITER; 123 list_append(& f->link, &frw->waiters);139 list_append(&wdata.wu_event.link, &frw->waiters); 124 140 fibril_switch(FIBRIL_TO_MANAGER); 125 141 } else { … … 134 150 if (frw->writers || frw->readers) { 135 151 fibril_t *f = (fibril_t *) fibril_get_id(); 152 awaiter_t wdata; 153 154 wdata.fid = (fid_t) f; 155 wdata.active = false; 156 wdata.wu_event.inlist = true; 157 link_initialize(&wdata.wu_event.link); 136 158 f->flags |= FIBRIL_WRITER; 137 list_append(& f->link, &frw->waiters);159 list_append(&wdata.wu_event.link, &frw->waiters); 138 160 fibril_switch(FIBRIL_TO_MANAGER); 139 161 } else { … … 158 180 while (!list_empty(&frw->waiters)) { 159 181 link_t *tmp = frw->waiters.next; 160 fibril_t *f = list_get_instance(tmp, fibril_t, link); 182 awaiter_t *wdp; 183 fibril_t *f; 184 185 wdp = list_get_instance(tmp, awaiter_t, wu_event.link); 186 f = (fibril_t *) wdp->fid; 161 187 162 188 if (f->flags & FIBRIL_WRITER) { 163 189 if (frw->readers) 164 190 break; 165 list_remove(&f->link); 166 fibril_add_ready((fid_t) f); 191 wdp->active = true; 192 wdp->wu_event.inlist = false; 193 list_remove(&wdp->wu_event.link); 194 fibril_add_ready(wdp->fid); 167 195 frw->writers++; 168 196 optimize_execution_power(); 169 197 break; 170 198 } else { 171 list_remove(&f->link); 172 fibril_add_ready((fid_t) f); 199 wdp->active = true; 200 wdp->wu_event.inlist = false; 201 list_remove(&wdp->wu_event.link); 202 fibril_add_ready(wdp->fid); 173 203 frw->readers++; 174 204 optimize_execution_power(); … … 194 224 } 195 225 196 void fibril_condvar_wait(fibril_condvar_t *fcv, fibril_mutex_t *fm) 197 { 198 fibril_t *f = (fibril_t *) fibril_get_id(); 199 200 futex_down(&async_futex); 201 list_append(&f->link, &fcv->waiters); 226 int 227 fibril_condvar_wait_timeout(fibril_condvar_t *fcv, fibril_mutex_t *fm, 228 suseconds_t timeout) 229 { 230 awaiter_t wdata; 231 232 if (timeout < 0) 233 return ETIMEOUT; 234 235 wdata.fid = fibril_get_id(); 236 wdata.active = false; 237 238 wdata.to_event.inlist = timeout > 0; 239 wdata.to_event.occurred = false; 240 link_initialize(&wdata.to_event.link); 241 242 wdata.wu_event.inlist = true; 243 link_initialize(&wdata.wu_event.link); 244 245 futex_down(&async_futex); 246 if (timeout) { 247 gettimeofday(&wdata.to_event.expires, NULL); 248 tv_add(&wdata.to_event.expires, timeout); 249 async_insert_timeout(&wdata); 250 } 251 list_append(&wdata.wu_event.link, &fcv->waiters); 202 252 _fibril_mutex_unlock_unsafe(fm); 203 253 fibril_switch(FIBRIL_TO_MANAGER); 204 254 fibril_mutex_lock(fm); 255 256 /* async_futex not held after fibril_switch() */ 257 futex_down(&async_futex); 258 if (wdata.to_event.inlist) 259 list_remove(&wdata.to_event.link); 260 if (wdata.wu_event.inlist) 261 list_remove(&wdata.wu_event.link); 262 futex_up(&async_futex); 263 264 return wdata.to_event.occurred ? ETIMEOUT : EOK; 265 } 266 267 void fibril_condvar_wait(fibril_condvar_t *fcv, fibril_mutex_t *fm) 268 { 269 int rc; 270 271 rc = fibril_condvar_wait_timeout(fcv, fm, 0); 272 assert(rc == EOK); 205 273 } 206 274 … … 208 276 { 209 277 link_t *tmp; 210 fibril_t *f;278 awaiter_t *wdp; 211 279 212 280 futex_down(&async_futex); 213 281 while (!list_empty(&fcv->waiters)) { 214 282 tmp = fcv->waiters.next; 215 f = list_get_instance(tmp, fibril_t, link); 216 list_remove(&f->link); 217 fibril_add_ready((fid_t) f); 218 optimize_execution_power(); 219 if (once) 220 break; 283 wdp = list_get_instance(tmp, awaiter_t, wu_event.link); 284 list_remove(&wdp->wu_event.link); 285 wdp->wu_event.inlist = false; 286 if (!wdp->active) { 287 wdp->active = true; 288 fibril_add_ready(wdp->fid); 289 optimize_execution_power(); 290 if (once) 291 break; 292 } 221 293 } 222 294 futex_up(&async_futex);
Note:
See TracChangeset
for help on using the changeset viewer.