Changes in uspace/lib/c/generic/fibril_synch.c [2654afb:45cbcaf4] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/fibril_synch.c
r2654afb r45cbcaf4 105 105 fibril_t *f = (fibril_t *) fibril_get_id(); 106 106 107 if (fibril_get_sercount() != 0) 108 abort(); 109 107 110 futex_down(&async_futex); 108 111 if (fm->counter-- <= 0) { … … 194 197 fibril_t *f = (fibril_t *) fibril_get_id(); 195 198 199 if (fibril_get_sercount() != 0) 200 abort(); 201 196 202 futex_down(&async_futex); 197 203 if (frw->writers) { … … 218 224 fibril_t *f = (fibril_t *) fibril_get_id(); 219 225 226 if (fibril_get_sercount() != 0) 227 abort(); 228 220 229 futex_down(&async_futex); 221 230 if (frw->writers || frw->readers) { … … 371 380 if (timeout) { 372 381 getuptime(&wdata.to_event.expires); 373 tv_add _diff(&wdata.to_event.expires, timeout);382 tv_add(&wdata.to_event.expires, timeout); 374 383 async_insert_timeout(&wdata); 375 384 } … … 439 448 int rc; 440 449 441 fibril_mutex_lock(timer->lockp); 442 443 while (timer->state != fts_cleanup) { 444 switch (timer->state) { 445 case fts_not_set: 446 case fts_fired: 447 fibril_condvar_wait(&timer->cv, timer->lockp); 450 fibril_mutex_lock(&timer->lock); 451 452 while (true) { 453 while (timer->state != fts_active && 454 timer->state != fts_cleanup) { 455 456 if (timer->state == fts_cleanup) 457 break; 458 459 fibril_condvar_wait(&timer->cv, &timer->lock); 460 } 461 462 if (timer->state == fts_cleanup) 448 463 break; 449 case fts_active: 450 rc = fibril_condvar_wait_timeout(&timer->cv, 451 timer->lockp, timer->delay); 452 if (rc == ETIMEOUT && timer->state == fts_active) { 453 timer->state = fts_fired; 454 timer->handler_fid = fibril_get_id(); 455 fibril_mutex_unlock(timer->lockp); 456 timer->fun(timer->arg); 457 fibril_mutex_lock(timer->lockp); 458 timer->handler_fid = 0; 459 } 460 break; 461 case fts_cleanup: 462 case fts_clean: 463 assert(false); 464 break; 464 465 rc = fibril_condvar_wait_timeout(&timer->cv, &timer->lock, 466 timer->delay); 467 if (rc == ETIMEOUT) { 468 timer->state = fts_fired; 469 fibril_mutex_unlock(&timer->lock); 470 timer->fun(timer->arg); 471 fibril_mutex_lock(&timer->lock); 465 472 } 466 473 } 467 474 468 /* Acknowledge timer fibril has finished cleanup. */ 469 timer->state = fts_clean; 470 fibril_condvar_broadcast(&timer->cv); 471 fibril_mutex_unlock(timer->lockp); 472 475 fibril_mutex_unlock(&timer->lock); 473 476 return 0; 474 477 } … … 478 481 * @return New timer on success, @c NULL if out of memory. 479 482 */ 480 fibril_timer_t *fibril_timer_create( fibril_mutex_t *lock)483 fibril_timer_t *fibril_timer_create(void) 481 484 { 482 485 fid_t fid; … … 498 501 timer->fibril = fid; 499 502 timer->state = fts_not_set; 500 timer->lockp = (lock != NULL) ? lock : &timer->lock;501 503 502 504 fibril_add_ready(fid); 505 503 506 return timer; 504 507 } … … 510 513 void fibril_timer_destroy(fibril_timer_t *timer) 511 514 { 512 fibril_mutex_lock(timer->lockp); 513 assert(timer->state == fts_not_set || timer->state == fts_fired); 514 515 /* Request timer fibril to terminate. */ 515 fibril_mutex_lock(&timer->lock); 516 assert(timer->state != fts_active); 516 517 timer->state = fts_cleanup; 517 518 fibril_condvar_broadcast(&timer->cv); 518 519 /* Wait for timer fibril to terminate */ 520 while (timer->state != fts_clean) 521 fibril_condvar_wait(&timer->cv, timer->lockp); 522 fibril_mutex_unlock(timer->lockp); 523 524 free(timer); 519 fibril_mutex_unlock(&timer->lock); 525 520 } 526 521 … … 538 533 fibril_timer_fun_t fun, void *arg) 539 534 { 540 fibril_mutex_lock(timer->lockp); 541 fibril_timer_set_locked(timer, delay, fun, arg); 542 fibril_mutex_unlock(timer->lockp); 543 } 544 545 /** Set locked timer. 546 * 547 * Set timer to execute a callback function after the specified 548 * interval. Must be called when the timer is locked. 549 * 550 * @param timer Timer 551 * @param delay Delay in microseconds 552 * @param fun Callback function 553 * @param arg Argument for @a fun 554 */ 555 void fibril_timer_set_locked(fibril_timer_t *timer, suseconds_t delay, 556 fibril_timer_fun_t fun, void *arg) 557 { 558 assert(fibril_mutex_is_locked(timer->lockp)); 559 assert(timer->state == fts_not_set || timer->state == fts_fired); 535 fibril_mutex_lock(&timer->lock); 560 536 timer->state = fts_active; 561 537 timer->delay = delay; … … 563 539 timer->arg = arg; 564 540 fibril_condvar_broadcast(&timer->cv); 541 fibril_mutex_unlock(&timer->lock); 565 542 } 566 543 … … 580 557 fibril_timer_state_t old_state; 581 558 582 fibril_mutex_lock(timer->lockp); 583 old_state = fibril_timer_clear_locked(timer); 584 fibril_mutex_unlock(timer->lockp); 585 586 return old_state; 587 } 588 589 /** Clear locked timer. 590 * 591 * Clears (cancels) timer and returns last state of the timer. 592 * This can be one of: 593 * - fts_not_set If the timer has not been set or has been cleared 594 * - fts_active Timer was set but did not fire 595 * - fts_fired Timer fired 596 * Must be called when the timer is locked. 597 * 598 * @param timer Timer 599 * @return Last timer state 600 */ 601 fibril_timer_state_t fibril_timer_clear_locked(fibril_timer_t *timer) 602 { 603 fibril_timer_state_t old_state; 604 605 assert(fibril_mutex_is_locked(timer->lockp)); 606 607 while (timer->handler_fid != 0) { 608 if (timer->handler_fid == fibril_get_id()) { 609 printf("Deadlock detected.\n"); 610 stacktrace_print(); 611 printf("Fibril %zx is trying to clear timer %p from " 612 "inside its handler %p.\n", 613 fibril_get_id(), timer, timer->fun); 614 abort(); 615 } 616 617 fibril_condvar_wait(&timer->cv, timer->lockp); 618 } 619 559 fibril_mutex_lock(&timer->lock); 620 560 old_state = timer->state; 621 561 timer->state = fts_not_set; … … 625 565 timer->arg = NULL; 626 566 fibril_condvar_broadcast(&timer->cv); 567 fibril_mutex_unlock(&timer->lock); 627 568 628 569 return old_state;
Note:
See TracChangeset
for help on using the changeset viewer.