#include #include #include #include #include #include #include "monitor_private.h" #include "monitor_ringbuf.h" struct monitor_ringbuf_wrap { ringbuf_t *ringbuf; char *ringbuf_data; unsigned long long push_number; // only for statistics unsigned long long push_bytes; // only for statistics unsigned long long pop_number; // only for statistics unsigned long long pop_bytes; // only for statistics }; ssize_t stm_ringbuf_stream_start(int thread_id, struct monitor_ringbuf_wrap *rbf, size_t require_size) { ringbuf_worker_t *rb_worker = ringbuf_register(rbf->ringbuf, thread_id); ssize_t offset = ringbuf_acquire(rbf->ringbuf, rb_worker, require_size); if (offset < 0) { STM_DBG_PRINT("stm ringbuf stream prealloc buffer(): ringbuf_acquire fail, no valid space!\n"); return 0; } return offset; } int stm_ringbuf_stream_append(int thread_id, struct monitor_ringbuf_wrap *rbf, size_t rbf_offset, const void *value, size_t len) { (void)thread_id; memcpy(rbf->ringbuf_data + rbf_offset, value, len); rbf->push_number++; rbf->push_bytes += len; return 0; } void stm_ringbuf_stream_finish(int thread_id, struct monitor_ringbuf_wrap *rbf) { ringbuf_worker_t *rb_worker = ringbuf_register(rbf->ringbuf, thread_id); ringbuf_produce(rbf->ringbuf, rb_worker); } int stm_ringbuf_easy_push(int thread_id, struct monitor_ringbuf_wrap *rbf, const void *push_value /*must continuous*/, size_t push_len) { ringbuf_worker_t *rb_worker = ringbuf_register(rbf->ringbuf, thread_id); ssize_t offset = ringbuf_acquire(rbf->ringbuf, rb_worker, push_len); if (offset < 0) { STM_DBG_PRINT("stm ringbuf easy push(): ringbuf_acquire fail, no valid space!\n"); return -1; } memcpy(rbf->ringbuf_data + offset, push_value, push_len); ringbuf_produce(rbf->ringbuf, rb_worker); rbf->push_number++; rbf->push_bytes += push_len; // STM_DBG_PRINT("stm ringbuf push() success, len:%llu, number:%llu\n", push_len, rbf->push_number); return 0; } void *stm_ringbuf_pop(struct monitor_ringbuf_wrap *rbf, size_t *pop_len) { size_t len = 0, offset = 0; len = ringbuf_consume(rbf->ringbuf, &offset); if (0 == len) { // STM_DBG_PRINT("stm_ringbuf_pop(): not valid data\n"); *pop_len = 0; return NULL; } rbf->pop_number++; *pop_len = len; // STM_DBG_PRINT("stm_ringbuf_pop() success, len:%llu, number:%llu\n", len, rbf->pop_number); return rbf->ringbuf_data + offset; } void stm_ringbuf_release(struct monitor_ringbuf_wrap *rbf, int rel_len) { ringbuf_release(rbf->ringbuf, rel_len); rbf->pop_bytes += rel_len; } struct monitor_ringbuf_wrap *stm_ringbuf_wrap_new(int thread_tot_num, size_t ringbuf_size) { struct monitor_ringbuf_wrap *rbf = (struct monitor_ringbuf_wrap *)calloc(1, sizeof(struct monitor_ringbuf_wrap)); size_t ringbuf_obj_size; ringbuf_get_sizes(thread_tot_num, &ringbuf_obj_size, NULL); rbf->ringbuf = (ringbuf_t *)calloc(1, ringbuf_obj_size); rbf->ringbuf_data = (char *)calloc(1, ringbuf_size); ringbuf_setup(rbf->ringbuf, thread_tot_num, ringbuf_size); return rbf; } void stm_ringbuf_wrap_free(struct monitor_ringbuf_wrap *rbf) { if (NULL == rbf) { return; } if (rbf->ringbuf) { free(rbf->ringbuf); } if (rbf->ringbuf_data) { free(rbf->ringbuf_data); } free(rbf); } void stm_ringbuf_get_statistics(const struct monitor_ringbuf_wrap *rbf, unsigned long long *push_number, unsigned long long *push_bytes, unsigned long long *pop_number, unsigned long long *pop_bytes) { if (NULL == rbf) { return; } if (push_number) { *push_number = rbf->push_number; } if (push_bytes) { *push_bytes = rbf->push_bytes; } if (pop_number) { *pop_number = rbf->pop_number; } if (pop_bytes) { *pop_bytes = rbf->pop_bytes; } }