示例#1
0
int pa_shmasyncq_push(pa_shmasyncq*l, void *p, int wait) {
    int idx;
    pa_atomic_ptr_t *cells;

    pa_assert(l);
    pa_assert(p);

    cells = PA_SHMASYNCQ_CELLS(l);

    _Y;
    idx = reduce(l, l->write_idx);

    if (!pa_atomic_ptr_cmpxchg(&cells[idx], NULL, p)) {

        if (!wait)
            return -1;

/*         pa_log("sleeping on push"); */

        do {
            pa_fdsem_wait(l->read_fdsem);
        } while (!pa_atomic_ptr_cmpxchg(&cells[idx], NULL, p));
    }

    _Y;
    l->write_idx++;

    pa_fdsem_post(l->write_fdsem);

    return 0;
}
示例#2
0
void* pa_flist_pop(pa_flist*l) {
    unsigned idx, n;
    pa_atomic_ptr_t *cells;
#ifdef PROFILE
    unsigned len;
#endif

    pa_assert(l);

    cells = PA_FLIST_CELLS(l);

    n = (unsigned) pa_atomic_load(&l->length) + N_EXTRA_SCAN;

#ifdef PROFILE
    len = n;
#endif

    _Y;
    idx = reduce(l, (unsigned) pa_atomic_load(&l->read_idx));

    for (; n > 0 ; n--) {
        void *p;

        _Y;
        p = pa_atomic_ptr_load(&cells[idx]);

        if (p) {

            _Y;
            if (!pa_atomic_ptr_cmpxchg(&cells[idx], p, NULL))
                continue;

            _Y;
            pa_atomic_inc(&l->read_idx);

            _Y;
            pa_atomic_dec(&l->length);

            return p;
        }

        _Y;
        idx = reduce(l, idx+1);
    }

#ifdef PROFILE
    if (len > N_EXTRA_SCAN)
        pa_log_warn("Didn't find used cell after %u iterations.", len);
#endif

    return NULL;
}
示例#3
0
int pa_flist_push(pa_flist*l, void *p) {
    unsigned idx, n;
    pa_atomic_ptr_t*cells;
#ifdef PROFILE
    unsigned len;
#endif

    pa_assert(l);
    pa_assert(p);

    cells = PA_FLIST_CELLS(l);

    n = l->size + N_EXTRA_SCAN - (unsigned) pa_atomic_load(&l->length);

#ifdef PROFILE
    len = n;
#endif

    _Y;
    idx = reduce(l, (unsigned) pa_atomic_load(&l->write_idx));

    for (; n > 0 ; n--) {

        _Y;

        if (pa_atomic_ptr_cmpxchg(&cells[idx], NULL, p)) {

            _Y;
            pa_atomic_inc(&l->write_idx);

            _Y;
            pa_atomic_inc(&l->length);

            return 0;
        }

        _Y;
        idx = reduce(l, idx + 1);
    }

#ifdef PROFILE
    if (len > N_EXTRA_SCAN)
        pa_log_warn("Didn't  find free cell after %u iterations.", len);
#endif

    return -1;
}
示例#4
0
/* This is a copy of the function in mutex-posix.c */
pa_mutex* pa_static_mutex_get(pa_static_mutex *s, bool recursive, bool inherit_priority) {
    pa_mutex *m;

    pa_assert(s);

    /* First, check if already initialized and short cut */
    if ((m = pa_atomic_ptr_load(&s->ptr)))
        return m;

    /* OK, not initialized, so let's allocate, and fill in */
    m = pa_mutex_new(recursive, inherit_priority);
    if ((pa_atomic_ptr_cmpxchg(&s->ptr, NULL, m)))
        return m;

    pa_mutex_free(m);

    /* Him, filling in failed, so someone else must have filled in
     * already */
    pa_assert_se(m = pa_atomic_ptr_load(&s->ptr));
    return m;
}
示例#5
0
void* pa_shmasyncq_pop(pa_shmasyncq*l, int wait) {
    int idx;
    void *ret;
    pa_atomic_ptr_t *cells;

    pa_assert(l);

    cells = PA_SHMASYNCQ_CELLS(l);

    _Y;
    idx = reduce(l, l->read_idx);

    if (!(ret = pa_atomic_ptr_load(&cells[idx]))) {

        if (!wait)
            return NULL;

/*         pa_log("sleeping on pop"); */

        do {
            pa_fdsem_wait(l->write_fdsem);
        } while (!(ret = pa_atomic_ptr_load(&cells[idx])));
    }

    pa_assert(ret);

    /* Guaranteed to succeed if we only have a single reader */
    pa_assert_se(pa_atomic_ptr_cmpxchg(&cells[idx], ret, NULL));

    _Y;
    l->read_idx++;

    pa_fdsem_post(l->read_fdsem);

    return ret;
}