This repository has been archived on 2025-09-14. You can view files and clone it, but cannot push or open issues or pull requests.
Files
stellar-stellar/infra/monitor/monitor_ringbuf.c
2024-11-07 18:30:58 +08:00

137 lines
4.0 KiB
C

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stddef.h>
#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;
}
}