Changeset 73a5857 in mainline for uspace/lib/usbhost/src/utility.c


Ignore:
Timestamp:
2018-01-31T23:31:05Z (7 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
53fdf8c
Parents:
2ca5a198
Message:

usbhost: add joinable_fibril utility

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usbhost/src/utility.c

    r2ca5a198 r73a5857  
    284284}
    285285
     286typedef struct joinable_fibril {
     287        fid_t fid;
     288        void *arg;
     289        fibril_worker_t worker;
     290
     291        bool running;
     292        fibril_mutex_t guard;
     293        fibril_condvar_t dead_cv;
     294} joinable_fibril_t;
     295
     296static int joinable_fibril_worker(void *arg)
     297{
     298        joinable_fibril_t *jf = arg;
     299        jf->worker(jf->arg);
     300
     301        fibril_mutex_lock(&jf->guard);
     302        jf->running = false;
     303        fibril_mutex_unlock(&jf->guard);
     304        fibril_condvar_broadcast(&jf->dead_cv);
     305        return 0;
     306}
     307
     308/**
     309 * Create a fibril that is joinable. Similar to fibril_create.
     310 */
     311joinable_fibril_t *joinable_fibril_create(fibril_worker_t worker, void *arg)
     312{
     313        joinable_fibril_t *jf = calloc(1, sizeof(joinable_fibril_t));
     314        if (!jf)
     315                return NULL;
     316
     317        jf->fid = fibril_create(joinable_fibril_worker, jf);
     318        if (!jf->fid) {
     319                free(jf);
     320                return NULL;
     321        }
     322
     323        jf->worker = worker;
     324        jf->arg = arg;
     325        fibril_mutex_initialize(&jf->guard);
     326        fibril_condvar_initialize(&jf->dead_cv);
     327
     328        return jf;
     329}
     330
     331
     332/**
     333 * Start a joinable fibril. Similar to fibril_add_ready.
     334 */
     335void joinable_fibril_start(joinable_fibril_t *jf)
     336{
     337        assert(jf);
     338        assert(!jf->running);
     339
     340        jf->running = true;
     341        fibril_add_ready(jf->fid);
     342}
     343
     344/**
     345 * Join a joinable fibril. Not similar to anything, obviously.
     346 */
     347void joinable_fibril_join(joinable_fibril_t *jf)
     348{
     349        assert(jf);
     350
     351        fibril_mutex_lock(&jf->guard);
     352        while (jf->running)
     353                fibril_condvar_wait(&jf->dead_cv, &jf->guard);
     354        fibril_mutex_unlock(&jf->guard);
     355}
     356
     357/**
     358 * Regular fibrils clean after themselves, joinable fibrils cannot.
     359 */
     360void joinable_fibril_destroy(joinable_fibril_t *jf)
     361{
     362        if (jf) {
     363                joinable_fibril_join(jf);
     364                free(jf);
     365        }
     366}
     367
    286368/**
    287369 * @}
Note: See TracChangeset for help on using the changeset viewer.