Changeset 2a3214e in mainline for uspace/lib/c/generic/fibril_synch.c
- Timestamp:
- 2011-10-26T16:50:52Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 8218b6b
- Parents:
- 6e88fea
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/fibril_synch.c
r6e88fea r2a3214e 447 447 } 448 448 449 /** Timer fibril. 450 * 451 * @param arg Timer 452 */ 453 static int fibril_timer_func(void *arg) 454 { 455 fibril_timer_t *timer = (fibril_timer_t *) arg; 456 int rc; 457 458 fibril_mutex_lock(&timer->lock); 459 460 while (true) { 461 while (timer->state != fts_active && 462 timer->state != fts_cleanup) { 463 464 if (timer->state == fts_cleanup) 465 break; 466 467 fibril_condvar_wait(&timer->cv, &timer->lock); 468 } 469 470 if (timer->state == fts_cleanup) 471 break; 472 473 rc = fibril_condvar_wait_timeout(&timer->cv, &timer->lock, 474 timer->delay); 475 if (rc == ETIMEOUT) { 476 timer->fun(timer->arg); 477 timer->state = fts_fired; 478 } 479 } 480 481 fibril_mutex_unlock(&timer->lock); 482 return 0; 483 } 484 485 /** Create new timer. 486 * 487 * @return New timer on success, @c NULL if out of memory. 488 */ 489 fibril_timer_t *fibril_timer_create(void) 490 { 491 fid_t fid; 492 fibril_timer_t *timer; 493 494 timer = calloc(1, sizeof(fibril_timer_t)); 495 if (timer == NULL) 496 return NULL; 497 498 fid = fibril_create(fibril_timer_func, (void *) timer); 499 if (fid == 0) { 500 free(timer); 501 return NULL; 502 } 503 504 fibril_mutex_initialize(&timer->lock); 505 fibril_condvar_initialize(&timer->cv); 506 507 timer->fibril = fid; 508 timer->state = fts_not_set; 509 510 fibril_add_ready(fid); 511 512 return timer; 513 } 514 515 /** Destroy timer. 516 * 517 * @param timer Timer, must not be active or accessed by other threads. 518 */ 519 void fibril_timer_destroy(fibril_timer_t *timer) 520 { 521 fibril_mutex_lock(&timer->lock); 522 assert(timer->state != fts_active); 523 timer->state = fts_cleanup; 524 fibril_condvar_broadcast(&timer->cv); 525 fibril_mutex_unlock(&timer->lock); 526 } 527 528 /** Set timer. 529 * 530 * Set timer to execute a callback function after the specified 531 * interval. 532 * 533 * @param timer Timer 534 * @param delay Delay in microseconds 535 * @param fun Callback function 536 * @param arg Argument for @a fun 537 */ 538 void fibril_timer_set(fibril_timer_t *timer, suseconds_t delay, 539 fibril_timer_fun_t fun, void *arg) 540 { 541 fibril_mutex_lock(&timer->lock); 542 timer->state = fts_active; 543 timer->delay = delay; 544 timer->fun = fun; 545 timer->arg = arg; 546 fibril_condvar_broadcast(&timer->cv); 547 fibril_mutex_unlock(&timer->lock); 548 } 549 550 /** Clear timer. 551 * 552 * Clears (cancels) timer and returns last state of the timer. 553 * This can be one of: 554 * - fts_not_set If the timer has not been set or has been cleared 555 * - fts_active Timer was set but did not fire 556 * - fts_fired Timer fired 557 * 558 * @param timer Timer 559 * @return Last timer state 560 */ 561 fibril_timer_state_t fibril_timer_clear(fibril_timer_t *timer) 562 { 563 fibril_timer_state_t old_state; 564 565 fibril_mutex_lock(&timer->lock); 566 old_state = timer->state; 567 timer->state = fts_not_set; 568 569 timer->delay = 0; 570 timer->fun = NULL; 571 timer->arg = NULL; 572 fibril_condvar_broadcast(&timer->cv); 573 fibril_mutex_unlock(&timer->lock); 574 575 return old_state; 576 } 577 449 578 /** @} 450 579 */
Note:
See TracChangeset
for help on using the changeset viewer.