/* cf_queue_push_limit
 * Push element on the queue only if size < limit.
 * */
bool cf_queue_push_limit(cf_queue *q, void *ptr, uint32_t limit) {
	QUEUE_LOCK(q);
	uint32_t size = CF_Q_SZ(q);

	if (size >= limit) {
		QUEUE_UNLOCK(q);
		return false;
	}

	/* Check queue length */
	if (size == q->allocsz) {
		/* resize is a pain for circular buffers */
		if (0 != cf_queue_resize(q, q->allocsz + CF_QUEUE_ALLOCSZ)) {
			QUEUE_UNLOCK(q);
			return false;
		}
	}

	memcpy(CF_Q_ELEM_PTR(q,q->write_offset), ptr, q->elementsz);
	q->write_offset++;
	// we're at risk of overflow if the write offset is that high
	if (q->write_offset & 0xC0000000) cf_queue_unwrap(q);

#ifndef EXTERNAL_LOCKS
	if (q->threadsafe)
		pthread_cond_signal(&q->CV);
#endif

	QUEUE_UNLOCK(q);
	return true;
}
/* cf_queue_push
 * Push goes to the front, which currently means memcpying the entire queue contents
 * */
int cf_queue_push(cf_queue *q, void *ptr) {
	/* FIXME arg check - and how do you do that, boyo? Magic numbers? */

	/* FIXME error */

	QUEUE_LOCK(q);

	/* Check queue length */
	if (CF_Q_SZ(q) == q->allocsz) {
		/* resize is a pain for circular buffers */
		if (0 != cf_queue_resize(q, q->allocsz + CF_QUEUE_ALLOCSZ)) {
			QUEUE_UNLOCK(q);
			return(-1);
		}
	}

	// todo: if queues are power of 2, this can be a shift
	memcpy(CF_Q_ELEM_PTR(q,q->write_offset), ptr, q->elementsz);
	q->write_offset++;
	// we're at risk of overflow if the write offset is that high
	if (q->write_offset & 0xC0000000) cf_queue_unwrap(q);

#ifndef EXTERNAL_LOCKS	
	if (q->threadsafe)
		pthread_cond_signal(&q->CV);
#endif 

	QUEUE_UNLOCK(q);

	return(0);
}
Beispiel #3
0
/* cf_queue_push
 *
 * */
int
cf_queue_push(cf_queue *q, void *ptr)
{
    /* FIXME arg check - and how do you do that, boyo? Magic numbers? */

    /* FIXME error */
    if (q->threadsafe && (0 != pthread_mutex_lock(&q->LOCK)))
        return(-1);

    /* Check queue length */
    if (CF_Q_SZ(q) == q->allocsz) {
        /* resize is a pain for circular buffers */
        if (0 != cf_queue_resize(q, q->allocsz * 2)) {
            if (q->threadsafe)
                pthread_mutex_unlock(&q->LOCK);
            // cf_warning(CF_QUEUE, "queue resize failure");
            return(-1);
        }
    }

    // todo: if queues are power of 2, this can be a shift
    memcpy(CF_Q_ELEM_PTR(q,q->write_offset), ptr, q->elementsz);
    q->write_offset++;
    // we're at risk of overflow if the write offset is that high
    if (q->write_offset & 0xC0000000) cf_queue_unwrap(q);

    if (q->threadsafe)
        pthread_cond_signal(&q->CV);

    /* FIXME blow a gasket */
    if (q->threadsafe && (0 != pthread_mutex_unlock(&q->LOCK)))
        return(-1);

    return(0);
}
Beispiel #4
0
/* cf_queue_push_head
 * Push head goes to the front, which currently means memcpying the entire queue contents
 * which is not the most optimal, but somewhat performant in most cases
 * */
int
cf_queue_push_head(cf_queue *q, void *ptr)
{

    /* FIXME error */
    if (q->threadsafe && (0 != pthread_mutex_lock(&q->LOCK)))
        return(-1);

    /* Check queue length */
    if (CF_Q_SZ(q) == q->allocsz) {
        /* resize is a pain for circular buffers */
        if (0 != cf_queue_resize(q, q->allocsz * 2)) {
            if (q->threadsafe)
                pthread_mutex_unlock(&q->LOCK);
            //cf_warning(CF_QUEUE, "queue resize failure");
            return(-1);
        }
    }

    // easy case, tail insert is head insert
    if (q->read_offset == q->write_offset) {
        memcpy(CF_Q_ELEM_PTR(q,q->write_offset), ptr, q->elementsz);
        q->write_offset++;
    }
    // another easy case, there's space up front
    else if (q->read_offset > 0) {
        q->read_offset--;
        memcpy(CF_Q_ELEM_PTR(q,q->read_offset), ptr, q->elementsz);
    }
    // hard case, we're going to have to shift everything back
    else {
        memmove(CF_Q_ELEM_PTR(q, 1),CF_Q_ELEM_PTR(q, 0),q->elementsz * CF_Q_SZ(q) );
        memcpy(CF_Q_ELEM_PTR(q,0), ptr, q->elementsz);
        q->write_offset++;
    }

    // we're at risk of overflow if the write offset is that high
    if (q->write_offset & 0xC0000000) cf_queue_unwrap(q);

    if (q->threadsafe)
        pthread_cond_signal(&q->CV);

    /* FIXME blow a gasket */
    if (q->threadsafe && (0 != pthread_mutex_unlock(&q->LOCK)))
        return(-1);

    return(0);
}