Changeset cadfa8e in mainline
- Timestamp:
- 2009-10-11T10:14:34Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 854ad23
- Parents:
- b6ee5b1
- Location:
- uspace/lib/libc
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/libc/generic/fibril_sync.c
rb6ee5b1 rcadfa8e 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 … … 194 197 } 195 198 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); 199 int 200 fibril_condvar_wait_timeout(fibril_condvar_t *fcv, fibril_mutex_t *fm, 201 suseconds_t timeout) 202 { 203 awaiter_t wdata; 204 205 if (timeout < 0) 206 return ETIMEOUT; 207 208 wdata.fid = fibril_get_id(); 209 wdata.active = false; 210 211 wdata.to_event.inlist = timeout > 0; 212 wdata.to_event.occurred = false; 213 link_initialize(&wdata.to_event.link); 214 215 wdata.wu_event.inlist = true; 216 link_initialize(&wdata.wu_event.link); 217 218 futex_down(&async_futex); 219 if (timeout) { 220 gettimeofday(&wdata.to_event.expires, NULL); 221 tv_add(&wdata.to_event.expires, timeout); 222 async_insert_timeout(&wdata); 223 } 224 list_append(&wdata.wu_event.link, &fcv->waiters); 202 225 _fibril_mutex_unlock_unsafe(fm); 203 226 fibril_switch(FIBRIL_TO_MANAGER); 204 227 fibril_mutex_lock(fm); 228 229 /* async_futex not held after fibril_switch() */ 230 futex_down(&async_futex); 231 if (wdata.to_event.inlist) 232 list_remove(&wdata.to_event.link); 233 if (wdata.wu_event.inlist) 234 list_remove(&wdata.wu_event.link); 235 futex_up(&async_futex); 236 237 return wdata.to_event.occurred ? ETIMEOUT : EOK; 238 } 239 240 void fibril_condvar_wait(fibril_condvar_t *fcv, fibril_mutex_t *fm) 241 { 242 int rc; 243 244 rc = fibril_condvar_wait_timeout(fcv, fm, 0); 245 assert(rc == EOK); 205 246 } 206 247 … … 208 249 { 209 250 link_t *tmp; 210 fibril_t *f;251 awaiter_t *wdp; 211 252 212 253 futex_down(&async_futex); 213 254 while (!list_empty(&fcv->waiters)) { 214 255 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; 256 wdp = list_get_instance(tmp, awaiter_t, wu_event.link); 257 list_remove(&wdp->wu_event.link); 258 wdp->wu_event.inlist = false; 259 if (!wdp->active) { 260 wdp->active = true; 261 fibril_add_ready(wdp->fid); 262 optimize_execution_power(); 263 if (once) 264 break; 265 } 221 266 } 222 267 futex_up(&async_futex); -
uspace/lib/libc/include/async_priv.h
rb6ee5b1 rcadfa8e 56 56 } to_event_t; 57 57 58 /** Structures of this type are used to track the wakeup events. */ 59 typedef struct { 60 /** If true, this struct is in a synchronization object wait queue. */ 61 bool inlist; 62 63 /** Wait queue linkage. */ 64 link_t link; 65 } wu_event_t; 66 67 58 68 /** Structures of this type represent a waiting fibril. */ 59 69 typedef struct { … … 66 76 /** Timeout wait data. */ 67 77 to_event_t to_event; 78 /** Wakeup wait data. */ 79 wu_event_t wu_event; 68 80 } awaiter_t; 69 81 -
uspace/lib/libc/include/fibril_sync.h
rb6ee5b1 rcadfa8e 40 40 #include <adt/list.h> 41 41 #include <libarch/tls.h> 42 #include <sys/time.h> 42 43 43 44 typedef struct { … … 95 96 96 97 extern void fibril_condvar_initialize(fibril_condvar_t *); 98 extern int fibril_condvar_wait_timeout(fibril_condvar_t *, fibril_mutex_t *, 99 suseconds_t); 97 100 extern void fibril_condvar_wait(fibril_condvar_t *, fibril_mutex_t *); 98 101 extern void fibril_condvar_signal(fibril_condvar_t *);
Note:
See TracChangeset
for help on using the changeset viewer.