/* 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); }
/* 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); }
/* 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); }