Skip to content

Commit

Permalink
Remove the oldest entry when Ringbuffer is full
Browse files Browse the repository at this point in the history
add ringbuffer full strategy to control whether remove the oldest log entry or discard new message

on dlt-daemon side in dlt.conf
when RingbufferFullStrategy = 0:    discard the new message
when RingbufferFullStrategy = 1:    remove the oldest entry in the ringbuffer

on application side
export DLT_USER_BUFFER_FULL_STRATEGY=0 to discard new message
export DLT_USER_BUFFER_FULL_STRATEGY=1 to remove the oldest entry in the ringbuffer
  • Loading branch information
jianjun-huang committed Jan 10, 2024
1 parent 2118762 commit d98c70e
Show file tree
Hide file tree
Showing 16 changed files with 342 additions and 229 deletions.
18 changes: 15 additions & 3 deletions include/dlt/dlt_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,14 @@ typedef enum
DLT_RECEIVE_FD
} DltReceiverType;

/**
* Type to specify what action to handle when ringbuffer is full
*/
typedef enum {
DLT_RINGBUFFER_DISCARD_NEW_MESSAGE,
DLT_RINGBUFFER_REMOVE_OLDEST_MESSAGE
} DltRingBufferFullStrategy;

/**
* The definition of the serial header containing the characters "DLS" + 0x01.
*/
Expand Down Expand Up @@ -795,6 +803,7 @@ typedef struct
uint32_t min_size; /**< Minimum size of buffer */
uint32_t max_size; /**< Maximum size of buffer */
uint32_t step_size; /**< Step size of buffer */
DltRingBufferFullStrategy full_strategy; /**< strategy when ringbuffer is full */
} DltBuffer;

typedef struct
Expand Down Expand Up @@ -1321,9 +1330,10 @@ DltReturnValue dlt_check_rcv_data_size(int received, int required);
* @param buf Pointer to ringbuffer structure
* @param ptr Ptr to ringbuffer memory
* @param size Maximum size of buffer in bytes
* @param full_strategy the strategy when ringbuffer is full
* @return negative value if there was an error
*/
DltReturnValue dlt_buffer_init_static_server(DltBuffer *buf, const unsigned char *ptr, uint32_t size);
DltReturnValue dlt_buffer_init_static_server(DltBuffer *buf, const unsigned char *ptr, uint32_t size, DltRingBufferFullStrategy full_strategy);

/**
* Initialize static ringbuffer with a size of size.
Expand All @@ -1332,9 +1342,10 @@ DltReturnValue dlt_buffer_init_static_server(DltBuffer *buf, const unsigned char
* @param buf Pointer to ringbuffer structure
* @param ptr Ptr to ringbuffer memory
* @param size Maximum size of buffer in bytes
* @param full_strategy the strategy when ringbuffer is full
* @return negative value if there was an error
*/
DltReturnValue dlt_buffer_init_static_client(DltBuffer *buf, const unsigned char *ptr, uint32_t size);
DltReturnValue dlt_buffer_init_static_client(DltBuffer *buf, const unsigned char *ptr, uint32_t size, DltRingBufferFullStrategy full_strategy);

/**
* Initialize dynamic ringbuffer with a size of size.
Expand All @@ -1346,9 +1357,10 @@ DltReturnValue dlt_buffer_init_static_client(DltBuffer *buf, const unsigned char
* @param min_size Minimum size of buffer in bytes
* @param max_size Maximum size of buffer in bytes
* @param step_size size of which ringbuffer is increased
* @param full_strategy the strategy when ringbuffer is full
* @return negative value if there was an error
*/
DltReturnValue dlt_buffer_init_dynamic(DltBuffer *buf, uint32_t min_size, uint32_t max_size, uint32_t step_size);
DltReturnValue dlt_buffer_init_dynamic(DltBuffer *buf, uint32_t min_size, uint32_t max_size, uint32_t step_size, DltRingBufferFullStrategy full_strategy);

/**
* Deinitilaise usage of static ringbuffer
Expand Down
6 changes: 4 additions & 2 deletions include/dlt/dlt_shm.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,19 +87,21 @@ typedef struct
* This function must be called before using further shm functions.
* @param buf pointer to shm structure
* @param name the name of the shm, must be the same for server and client
* @param full_strategy the strategy when ringbuffer is full
* @return negative value if there was an error
*/
extern DltReturnValue dlt_shm_init_client(DltShm *buf, const char *name);
extern DltReturnValue dlt_shm_init_client(DltShm *buf, const char *name, DltRingBufferFullStrategy full_strategy);

/**
* Initialise the shared memory on the server side.
* This function must be called before using further shm functions.
* @param buf pointer to shm structure
* @param name the name of the shm, must be the same for server and client
* @param size the requested size of the shm
* @param full_strategy the strategy when ringbuffer is full
* @return negative value if there was an error
*/
extern DltReturnValue dlt_shm_init_server(DltShm *buf, const char *name, int size);
extern DltReturnValue dlt_shm_init_server(DltShm *buf, const char *name, int size, DltRingBufferFullStrategy full_strategy);

/**
* Push data from client onto the shm.
Expand Down
1 change: 1 addition & 0 deletions include/dlt/dlt_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ typedef unsigned int speed_t;
*/
typedef enum
{
DLT_RETURN_NO_INCREASE_SIZE = -9,
DLT_RETURN_FILESZERR = -8,
DLT_RETURN_LOGGING_DISABLED = -7,
DLT_RETURN_USER_BUFFER_FULL = -6,
Expand Down
9 changes: 7 additions & 2 deletions src/daemon/dlt-daemon.c
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,7 @@ int option_file_parser(DltDaemonLocal *daemon_local)
daemon_local->RingbufferMinSize = DLT_DAEMON_RINGBUFFER_MIN_SIZE;
daemon_local->RingbufferMaxSize = DLT_DAEMON_RINGBUFFER_MAX_SIZE;
daemon_local->RingbufferStepSize = DLT_DAEMON_RINGBUFFER_STEP_SIZE;
daemon_local->ringbufferFullStrategy = DLT_RINGBUFFER_DISCARD_NEW_MESSAGE;
daemon_local->daemonFifoSize = 0;
daemon_local->flags.sendECUSoftwareVersion = 0;
memset(daemon_local->flags.pathToECUSoftwareVersion, 0, sizeof(daemon_local->flags.pathToECUSoftwareVersion));
Expand Down Expand Up @@ -592,6 +593,10 @@ int option_file_parser(DltDaemonLocal *daemon_local)
value, &(daemon_local->RingbufferStepSize)) < 0)
return -1;
}
else if (strcmp(token, "RingbufferFullStrategy") == 0)
{
daemon_local->ringbufferFullStrategy = (DltRingBufferFullStrategy)atoi(value);
}
else if (strcmp(token, "SharedMemorySize") == 0)
{
daemon_local->flags.sharedMemorySize = atoi(value);
Expand Down Expand Up @@ -1428,7 +1433,7 @@ int dlt_daemon_local_init_p2(DltDaemon *daemon, DltDaemonLocal *daemon_local, in

/* Daemon data */
if (dlt_daemon_init(daemon, daemon_local->RingbufferMinSize, daemon_local->RingbufferMaxSize,
daemon_local->RingbufferStepSize, daemon_local->flags.ivalue,
daemon_local->RingbufferStepSize, daemon_local->ringbufferFullStrategy, daemon_local->flags.ivalue,
daemon_local->flags.contextLogLevel,
daemon_local->flags.contextTraceStatus, daemon_local->flags.enforceContextLLAndTS,
daemon_local->flags.vflag) == -1) {
Expand Down Expand Up @@ -1477,7 +1482,7 @@ int dlt_daemon_local_init_p2(DltDaemon *daemon, DltDaemonLocal *daemon_local, in

/* init shared memory */
if (dlt_shm_init_server(&(daemon_local->dlt_shm), daemon_local->flags.dltShmName,
daemon_local->flags.sharedMemorySize) == DLT_RETURN_ERROR) {
daemon_local->flags.sharedMemorySize, daemon_local->ringbufferFullStrategy) == DLT_RETURN_ERROR) {
dlt_log(LOG_ERR, "Could not initialize shared memory\n");
return -1;
}
Expand Down
1 change: 1 addition & 0 deletions src/daemon/dlt-daemon.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ typedef struct
unsigned long RingbufferMinSize;
unsigned long RingbufferMaxSize;
unsigned long RingbufferStepSize;
DltRingBufferFullStrategy ringbufferFullStrategy; /**< (DltRingBufferFullStrategy) indicates what action to handle when hte ringbuffer is full*/
unsigned long daemonFifoSize;
#ifdef UDP_CONNECTION_SUPPORT
int UDPConnectionSetup; /* enable/disable the UDP connection */
Expand Down
5 changes: 5 additions & 0 deletions src/daemon/dlt.conf
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ RingbufferMaxSize = 10000000
# The step size the Ringbuffer is increased, used for storing temporary DLT messages, until client is connected (Default: 500000)
RingbufferStepSize = 500000

# Indicate whether remove the oldest entry in the RingBuffer when ringBuffer is full (Default: 0)
# 0 = discard new messages
# 1 = remove the oldest message in the ringbuffer
RingbufferFullStrategy = 0

# The size of Daemon FIFO (/tmp/dlt) (Default: 65536, MinSize: depend on pagesize of system, MaxSize: please check /proc/sys/fs/pipe-max-size)
# This is only supported for Linux.
# DaemonFIFOSize = 65536
Expand Down
4 changes: 3 additions & 1 deletion src/daemon/dlt_daemon_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ int dlt_daemon_init(DltDaemon *daemon,
unsigned long RingbufferMinSize,
unsigned long RingbufferMaxSize,
unsigned long RingbufferStepSize,
DltRingBufferFullStrategy ringBufferFullStrategy,
const char *runtime_directory,
int InitialContextLogLevel,
int InitialContextTraceStatus,
Expand Down Expand Up @@ -325,7 +326,8 @@ int dlt_daemon_init(DltDaemon *daemon,
if (dlt_buffer_init_dynamic(&(daemon->client_ringbuffer),
(uint32_t) RingbufferMinSize,
(uint32_t) RingbufferMaxSize,
(uint32_t) RingbufferStepSize) < DLT_RETURN_OK)
(uint32_t) RingbufferStepSize,
ringBufferFullStrategy) < DLT_RETURN_OK)
return -1;

daemon->storage_handle = NULL;
Expand Down
2 changes: 2 additions & 0 deletions src/daemon/dlt_daemon_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ typedef struct
* @param RingbufferMinSize ringbuffer size
* @param RingbufferMaxSize ringbuffer size
* @param RingbufferStepSize ringbuffer size
* @param fullStrategy ringbuffer full strategy
* @param runtime_directory Directory of persistent configuration
* @param InitialContextLogLevel loglevel to be sent to context when those register with loglevel default, read from dlt.conf
* @param InitialContextTraceStatus tracestatus to be sent to context when those register with tracestatus default, read from dlt.conf
Expand All @@ -224,6 +225,7 @@ int dlt_daemon_init(DltDaemon *daemon,
unsigned long RingbufferMinSize,
unsigned long RingbufferMaxSize,
unsigned long RingbufferStepSize,
DltRingBufferFullStrategy fullStrategy,
const char *runtime_directory,
int InitialContextLogLevel,
int InitialContextTraceStatus,
Expand Down
29 changes: 26 additions & 3 deletions src/lib/dlt_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,8 @@ static DltReturnValue dlt_user_log_write_sized_string_utils_attr(DltContextData

static DltReturnValue dlt_unregister_app_util(bool force_sending_messages);

static DltRingBufferFullStrategy dlt_env_get_ringbuffer_full_strategy();

DltReturnValue dlt_user_check_library_version(const char *user_major_version, const char *user_minor_version)
{
char lib_major_version[DLT_USER_MAX_LIB_VERSION_LENGTH];
Expand Down Expand Up @@ -501,7 +503,7 @@ DltReturnValue dlt_init(void)
memset(&(dlt_user.dlt_shm), 0, sizeof(DltShm));

/* init shared memory */
if (dlt_shm_init_client(&(dlt_user.dlt_shm), dltShmName) < DLT_RETURN_OK)
if (dlt_shm_init_client(&(dlt_user.dlt_shm), dltShmName, dlt_env_get_ringbuffer_full_strategy()) < DLT_RETURN_OK)
dlt_vnlog(LOG_WARNING, DLT_USER_BUFFER_LENGTH, "Logging disabled,"
" Shared memory %s cannot be created!\n", dltShmName);

Expand Down Expand Up @@ -883,7 +885,8 @@ DltReturnValue dlt_init_common(void)
if (dlt_buffer_init_dynamic(&(dlt_user.startup_buffer),
buffer_min,
buffer_max,
buffer_step) == DLT_RETURN_ERROR) {
buffer_step,
dlt_env_get_ringbuffer_full_strategy()) == DLT_RETURN_ERROR) {
dlt_user_init_state = INIT_UNITIALIZED;
DLT_SEM_FREE();
return DLT_RETURN_ERROR;
Expand Down Expand Up @@ -4920,7 +4923,7 @@ void dlt_user_log_reattach_to_daemon(void)
#ifdef DLT_SHM_ENABLE

/* init shared memory */
if (dlt_shm_init_client(&dlt_user.dlt_shm, dltShmName) < DLT_RETURN_OK)
if (dlt_shm_init_client(&dlt_user.dlt_shm, dltShmName,dlt_env_get_ringbuffer_full_strategy()) < DLT_RETURN_OK)
dlt_vnlog(LOG_WARNING, DLT_USER_BUFFER_LENGTH, "Logging disabled,"
" Shared memory %s cannot be created!\n", dltShmName);

Expand Down Expand Up @@ -5200,3 +5203,23 @@ DltReturnValue dlt_user_log_out_error_handling(void *ptr1, size_t len1, void *pt

return ret;
}

DltRingBufferFullStrategy dlt_env_get_ringbuffer_full_strategy()
{
char *env_buffer_full_strategy = NULL;
DltRingBufferFullStrategy full_strategy = DLT_RINGBUFFER_DISCARD_NEW_MESSAGE;

env_buffer_full_strategy = getenv(DLT_USER_ENV_BUFFER_FULL_STRATEGY);
if (env_buffer_full_strategy != NULL) {
full_strategy = (DltRingBufferFullStrategy)strtol(env_buffer_full_strategy, NULL, 10);

if ((errno == EINVAL) || (errno == ERANGE)) {
dlt_vlog(LOG_ERR,
"Wrong value specified for %s. Using default\n",
DLT_USER_ENV_BUFFER_FULL_STRATEGY);
full_strategy = DLT_RINGBUFFER_DISCARD_NEW_MESSAGE;
}
}

return full_strategy;
}
1 change: 1 addition & 0 deletions src/lib/dlt_user_cfg.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
#define DLT_USER_ENV_BUFFER_MIN_SIZE "DLT_USER_BUFFER_MIN"
#define DLT_USER_ENV_BUFFER_MAX_SIZE "DLT_USER_BUFFER_MAX"
#define DLT_USER_ENV_BUFFER_STEP_SIZE "DLT_USER_BUFFER_STEP"
#define DLT_USER_ENV_BUFFER_FULL_STRATEGY "DLT_USER_BUFFER_FULL_STRATEGY"

/* Temporary buffer length */
#define DLT_USER_BUFFER_LENGTH 255
Expand Down
60 changes: 53 additions & 7 deletions src/shared/dlt_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ int dlt_buffer_increase_size(DltBuffer *buf);
int dlt_buffer_minimize_size(DltBuffer *buf);
void dlt_buffer_write_block(DltBuffer *buf, int *write, const unsigned char *data, unsigned int size);
void dlt_buffer_read_block(DltBuffer *buf, int *read, unsigned char *data, unsigned int size);
DltReturnValue dlt_buffer_skip_size(DltBuffer *buf, int skip_size);

void dlt_print_hex(uint8_t *ptr, int size)
{
Expand Down Expand Up @@ -2375,7 +2376,7 @@ DltReturnValue dlt_check_storageheader(DltStorageHeader *storageheader)
? DLT_RETURN_TRUE : DLT_RETURN_OK;
}

DltReturnValue dlt_buffer_init_static_server(DltBuffer *buf, const unsigned char *ptr, uint32_t size)
DltReturnValue dlt_buffer_init_static_server(DltBuffer *buf, const unsigned char *ptr, uint32_t size, DltRingBufferFullStrategy full_strategy)
{
if ((buf == NULL) || (ptr == NULL))
return DLT_RETURN_WRONG_PARAMETER;
Expand All @@ -2398,6 +2399,7 @@ DltReturnValue dlt_buffer_init_static_server(DltBuffer *buf, const unsigned char

/* clear memory */
memset(buf->mem, 0, buf->size);
buf->full_strategy = full_strategy;

dlt_vlog(LOG_DEBUG,
"%s: Buffer: Size %u, Start address %lX\n",
Expand All @@ -2406,7 +2408,7 @@ DltReturnValue dlt_buffer_init_static_server(DltBuffer *buf, const unsigned char
return DLT_RETURN_OK; /* OK */
}

DltReturnValue dlt_buffer_init_static_client(DltBuffer *buf, const unsigned char *ptr, uint32_t size)
DltReturnValue dlt_buffer_init_static_client(DltBuffer *buf, const unsigned char *ptr, uint32_t size, DltRingBufferFullStrategy full_strategy)
{
if ((buf == NULL) || (ptr == NULL))
return DLT_RETURN_WRONG_PARAMETER;
Expand All @@ -2420,6 +2422,7 @@ DltReturnValue dlt_buffer_init_static_client(DltBuffer *buf, const unsigned char
/* Init pointers */
buf->mem = (unsigned char *)(buf->shm + sizeof(DltBufferHead));
buf->size = (uint32_t)(buf->min_size - sizeof(DltBufferHead));
buf->full_strategy = full_strategy;

dlt_vlog(LOG_DEBUG,
"%s: Buffer: Size %u, Start address %lX\n",
Expand All @@ -2428,7 +2431,7 @@ DltReturnValue dlt_buffer_init_static_client(DltBuffer *buf, const unsigned char
return DLT_RETURN_OK; /* OK */
}

DltReturnValue dlt_buffer_init_dynamic(DltBuffer *buf, uint32_t min_size, uint32_t max_size, uint32_t step_size)
DltReturnValue dlt_buffer_init_dynamic(DltBuffer *buf, uint32_t min_size, uint32_t max_size, uint32_t step_size, DltRingBufferFullStrategy full_strategy)
{
/*Do not DLT_SEM_LOCK inside here! */
DltBufferHead *head;
Expand Down Expand Up @@ -2485,6 +2488,8 @@ DltReturnValue dlt_buffer_init_dynamic(DltBuffer *buf, uint32_t min_size, uint32
/* clear memory */
memset(buf->mem, 0, (size_t)buf->size);

buf->full_strategy = full_strategy;

return DLT_RETURN_OK; /* OK */
}

Expand Down Expand Up @@ -2604,12 +2609,12 @@ int dlt_buffer_increase_size(DltBuffer *buf)
/* check size */
if (buf->step_size == 0)
/* cannot increase size */
return DLT_RETURN_ERROR;
return DLT_RETURN_NO_INCREASE_SIZE;

/* check size */
if ((buf->size + sizeof(DltBufferHead) + buf->step_size) > buf->max_size)
/* max size reached, do not increase */
return DLT_RETURN_ERROR;
return DLT_RETURN_NO_INCREASE_SIZE;

/* allocate new buffer */
new_ptr = malloc(buf->size + sizeof(DltBufferHead) + buf->step_size);
Expand Down Expand Up @@ -2656,6 +2661,39 @@ int dlt_buffer_increase_size(DltBuffer *buf)
return DLT_RETURN_OK; /* OK */
}

DltReturnValue dlt_buffer_skip_size(DltBuffer *buf, int skip_size){
/* catch null pointer */
if (buf == NULL) {
dlt_vlog(LOG_WARNING, "%s: Wrong parameter: Null pointer\n", __func__);
return DLT_RETURN_WRONG_PARAMETER;
}

if (buf->size < skip_size) {
dlt_vlog(LOG_WARNING, "%s: Wrong parameter: Null pointer\n", __func__);
return DLT_RETURN_WRONG_PARAMETER;
}

DltBufferHead *head = (DltBufferHead *)buf->shm;
int free_size = 0;

while(free_size < skip_size && head->count) {
DltBufferBlockHead block_head;
/* read header */
dlt_buffer_read_block(buf, &head->read, (unsigned char *)&block_head, sizeof(DltBufferBlockHead));

head->read = head->read + block_head.size;
if ((unsigned int) (head->read) >= buf->size) {
head->read = (unsigned int)(head->read) - buf->size;
}

head->count = head->count -1 ;
free_size = (int)sizeof(DltBufferBlockHead) + block_head.size;
dlt_vlog(LOG_DEBUG, "Clearing needed memory from buffer - need memory(%d) free memory(%d)\n", skip_size, free_size);
}

return DLT_RETURN_OK;
}

int dlt_buffer_minimize_size(DltBuffer *buf)
{
unsigned char *new_ptr;
Expand Down Expand Up @@ -2778,10 +2816,18 @@ int dlt_buffer_push3(DltBuffer *buf,
/* check size */
while (free_size < (int) (sizeof(DltBufferBlockHead) + size1 + size2 + size3)) {
/* try to increase size if possible */
if (dlt_buffer_increase_size(buf))
int ret = dlt_buffer_increase_size(buf);
if (ret <0) {
if( buf->full_strategy == DLT_RINGBUFFER_REMOVE_OLDEST_MESSAGE && ret == DLT_RETURN_NO_INCREASE_SIZE) {
ret = dlt_buffer_skip_size(buf, (int) (sizeof(DltBufferBlockHead) + size1 + size2 + size3));
}

if (ret <0) {
/* increase size is not possible */
/*dlt_log(LOG_ERR, "Buffer: Buffer is full\n"); */
return DLT_RETURN_ERROR; /* ERROR */
return ret; /* ERROR */
}
}

/* update pointers */
write = ((int *)(buf->shm))[0];
Expand Down
Loading

0 comments on commit d98c70e

Please sign in to comment.