misc_ringbuff.h from EmStar at Krugle
Show misc_ringbuff.h syntax highlighted
/*
*
* Copyright (c) 2003 The Regents of the University of California. All
* rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of the University nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* \file misc_ringbuff.h Ring Buffer
*/
#ifndef __RING_BUFF_H_
#define __RING_BUFF_H_
#include "libmisc/misc.h"
#include <time.h>
#include "timesync/sync_structs.h"
#include <glib.h>
#define RB_DEF_SIZE 40000 //--fixme-- what should this be?
#define RB_DEF_SAMPLSZ 2
typedef struct rb_ctx rb_ctx_t;
/** If want to use the search function, then need to specifiy
* a comparison function */
typedef int (*rb_compare) (void* x, void* y);
/** \brief Options to initialize a new ring-buffer */
typedef struct rb_opts {
/** Number of samples to store in the ring-buffer */
int num_samples;
/** size of each samples - if this is 0,
* then assume each sample is variable-length. This is less
* efficient - so if possible, specify this value */
size_t sample_size;
/** If want to be able to search the values, then specify
* a comparator function. This comparator compare the two
* values, and return the difference. */
rb_compare comparator;
} rb_opts_t;
typedef struct rb_hdr_info {
uint64_t first_sample;
int num_samples;
} rb_hdr_info_t;
typedef struct rb_rsp {
rb_hdr_info_t hdr;
/** For variable-length samples, allocate this pointer to
* get a vector of sample-sizes for each sample */
buf_t *sample_size;
/** Client Must allocate this buf to get data back */
buf_t *Dbuf;
} rb_rsp_t;
/** \brief Push a sample onto rb.
* Arguments:
* \a data_len: For variable-length samples, this field MUST be
* \a set, for fixed-length samples, it is ignored.
* \a num_samples: For variable-length samples, can only push
* \a one sample at a time.
* Returns: Sets sample_clk (if its a valid ptr) to the sample_clk for the
* sample.
*/
int rb_sample_push(rb_ctx_t * rb, void *smpl, int num_samples,
size_t data_len, uint64_t* sample_clk);
/** \brief Return data that falls between start and stop
* Arguments:
* \a max_data_len: how much data the client wants to receive. If set
* to 0, then all possible data is returned.
* NOTE: Partial samples are NOT returned - so if
* max_data_len < sampleSize then no data will be returned
* \a num_samples: how many samples client wants to receive, if set to
* 0, then return all samples possible
* Returns: if rb is empty or the request is in the future, returns 0
* if request is too old, reutrns - 1
*/
int rb_get_data(rb_ctx_t * rb, uint64_t first_sample,
int num_samples, size_t max_data_len, rb_rsp_t * rsp);
/**
* Returns samples which fall into the range specified.
* The rb must have values stored in ascending order. In order
* to use this function, must have specified a comparator function
* in rb_opts_t or using rb_set_comparator.
* This comparator function will then be used to
* determine which samples fall into the range specified by
* rstart and rstop
*/
int rb_return_range(rb_ctx_t* rb, rb_rsp_t* rsp, void* rstart, void* rstop);
/**
* Works similar to above, but it performs a best-effort. So, if
* the start of the request falls between two samples, then the
* lower sample will be included. If the start & stop are greater than
* the last sample, the last sample will still be included anyways.
* This works for isochronous data for the timehist-buffer which
* needs these semantics
*/
int rb_ret_range_best_eff(rb_ctx_t* rb, rb_rsp_t* rsp, void* rstart, void* rstop);
/* clears a response struct, optionally deallocating buffers */
void rb_response_clear(rb_rsp_t *rsp, int dealloc);
/** Works similar to above, but values in rb do NOT have to be stored
* in ascending order. In addition, only ONE sample is returned. This
* sample must match the match_value arg as determined by rb_compare* func-ptr
* specified in rb_opts. It will return a pointer to the matching sample
*/
void* rb_return_matching_sample(rb_ctx_t* rb, void* match_value);
uint64_t rb_get_last_sampleNum(rb_ctx_t * rb);
uint64_t rb_get_first_sampleNum(rb_ctx_t * rb);
/**
* Returns size of sample, data points to sample.
* \a len: expected length of sample and amount of memory pointed to
* by data. Included for safety purposes.
*/
size_t rb_get_last_sample(rb_ctx_t * rb, void* data, int len);
size_t rb_get_sample(rb_ctx_t * rb, uint64_t sample_num, void* data, int len);
size_t rb_get_first_sample(rb_ctx_t * rb, void* data, int len);
/* Accessor information */
/** Determines if ring-buff has variable-length samples
* or fixed-length */
int rb_variable_len_samples(rb_ctx_t * rb);
int rb_empty(rb_ctx_t * rb);
int rb_full(rb_ctx_t * rb);
/** If no samples have been pushed onto the ring-buffer,
* then the first sample-number assigned to a sample can
* be assigned */
int rb_set_start_sample(rb_ctx_t *rb, uint64_t start_sample);
/* Constructor/Destructor */
/** \brief Initialize a new ring-buffer
* Arguments:
* \a sampleSz - size of each sample, if 0 than variable len smpls assumed
* \a size - If sampleSz == 0, refers to # samples ring-buff should hold.
* Else, refers to # bytes ring-buff should hold (so
* num-samples = size/sampleSz.
*
* Allowable Formats:
* - fixed-sample-len
* - variable-sample-len
* Returns: Starting sample-clock - in case another buffer wants to
* store the offset between its sample-mappings and what ring-buff
* returns. Assumption is based on the fact that rb assigns
* continguous sample-numbers.
*/
int rb_new(rb_opts_t* r_opts, rb_ctx_t** rb_ref);
void rb_destroy(rb_ctx_t * rb);
#endif
See more files for this project here