Changeset d742db21 in mainline


Ignore:
Timestamp:
2018-08-01T18:15:53Z (6 years ago)
Author:
Jiří Zárevúcky <jiri.zarevucky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
6340b4d2
Parents:
6bb136b2
git-author:
Jiří Zárevúcky <jiri.zarevucky@…> (2018-07-30 21:07:49)
git-committer:
Jiří Zárevúcky <jiri.zarevucky@…> (2018-08-01 18:15:53)
Message:

Implement down_timeout() and close() operations for fibril semaphore.

Location:
uspace/lib/c
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/fibril_synch.c

    r6bb136b2 rd742db21  
    664664         */
    665665        assert(count >= 0);
     666        sem->closed = false;
    666667        sem->count = count;
    667668        list_initialize(&sem->waiters);
     
    679680{
    680681        futex_lock(&fibril_synch_futex);
     682
     683        if (sem->closed) {
     684                futex_unlock(&fibril_synch_futex);
     685                return;
     686        }
     687
    681688        sem->count++;
    682689
     
    700707{
    701708        futex_lock(&fibril_synch_futex);
     709
     710        if (sem->closed) {
     711                futex_unlock(&fibril_synch_futex);
     712                return;
     713        }
     714
    702715        sem->count--;
    703716
     
    715728}
    716729
     730errno_t fibril_semaphore_down_timeout(fibril_semaphore_t *sem, suseconds_t timeout)
     731{
     732        if (timeout < 0)
     733                return ETIMEOUT;
     734
     735        futex_lock(&fibril_synch_futex);
     736        if (sem->closed) {
     737                futex_unlock(&fibril_synch_futex);
     738                return EOK;
     739        }
     740
     741        sem->count--;
     742
     743        if (sem->count >= 0) {
     744                futex_unlock(&fibril_synch_futex);
     745                return EOK;
     746        }
     747
     748        awaiter_t wdata = AWAITER_INIT;
     749        list_append(&wdata.link, &sem->waiters);
     750
     751        futex_unlock(&fibril_synch_futex);
     752
     753        struct timeval tv;
     754        struct timeval *expires = NULL;
     755        if (timeout) {
     756                getuptime(&tv);
     757                tv_add_diff(&tv, timeout);
     758                expires = &tv;
     759        }
     760
     761        errno_t rc = fibril_wait_timeout(&wdata.event, expires);
     762        if (rc == EOK)
     763                return EOK;
     764
     765        futex_lock(&fibril_synch_futex);
     766        if (!link_in_use(&wdata.link)) {
     767                futex_unlock(&fibril_synch_futex);
     768                return EOK;
     769        }
     770
     771        list_remove(&wdata.link);
     772        sem->count++;
     773        futex_unlock(&fibril_synch_futex);
     774
     775        return rc;
     776}
     777
     778/**
     779 * Close the semaphore.
     780 * All future down() operations return instantly.
     781 */
     782void fibril_semaphore_close(fibril_semaphore_t *sem)
     783{
     784        futex_lock(&fibril_synch_futex);
     785        sem->closed = true;
     786        awaiter_t *w;
     787
     788        while ((w = list_pop(&sem->waiters, awaiter_t, link)))
     789                fibril_notify(&w->event);
     790
     791        futex_unlock(&fibril_synch_futex);
     792}
     793
    717794/** @}
    718795 */
  • uspace/lib/c/include/fibril_synch.h

    r6bb136b2 rd742db21  
    186186        long int count;
    187187        list_t waiters;
     188        bool closed;
    188189} fibril_semaphore_t;
    189190
     
    241242extern void fibril_semaphore_up(fibril_semaphore_t *);
    242243extern void fibril_semaphore_down(fibril_semaphore_t *);
     244extern errno_t fibril_semaphore_down_timeout(fibril_semaphore_t *, suseconds_t);
     245extern void fibril_semaphore_close(fibril_semaphore_t *);
    243246
    244247#endif
Note: See TracChangeset for help on using the changeset viewer.