143 lines
2.8 KiB
C
143 lines
2.8 KiB
C
|
|
/* SPDX-License-Identifier: Apache-2.0 */
|
||
|
|
/**
|
||
|
|
* @file duplexqueue.c
|
||
|
|
*
|
||
|
|
* @brief Code file for Duplex Queue library
|
||
|
|
*
|
||
|
|
* @copyright Copyright (C) 2024 Jackrabbit Founders LLC. All rights reserved.
|
||
|
|
*
|
||
|
|
* @date Feb 2024
|
||
|
|
* @author Barrett Edwards <code@jrlabs.io>
|
||
|
|
*
|
||
|
|
*/
|
||
|
|
|
||
|
|
/* INCLUDES ==================================================================*/
|
||
|
|
|
||
|
|
/* free()
|
||
|
|
*/
|
||
|
|
#include <stdlib.h>
|
||
|
|
|
||
|
|
/* printf()
|
||
|
|
*/
|
||
|
|
#include <stdio.h>
|
||
|
|
|
||
|
|
/* errno
|
||
|
|
*/
|
||
|
|
#include <errno.h>
|
||
|
|
|
||
|
|
/* memset()
|
||
|
|
*/
|
||
|
|
#include <string.h>
|
||
|
|
|
||
|
|
/* __u32
|
||
|
|
* __s32
|
||
|
|
*/
|
||
|
|
#include <linux/types.h>
|
||
|
|
|
||
|
|
#include <ptrqueue.h>
|
||
|
|
|
||
|
|
#include "duplexqueue.h"
|
||
|
|
|
||
|
|
|
||
|
|
/* MACROS ====================================================================*/
|
||
|
|
|
||
|
|
/* ENUMERATIONS ==============================================================*/
|
||
|
|
|
||
|
|
/* STRUCTS ===================================================================*/
|
||
|
|
|
||
|
|
/* GLOBAL VARIABLES ==========================================================*/
|
||
|
|
|
||
|
|
/* PROTOTYPES ================================================================*/
|
||
|
|
|
||
|
|
/* FUNCTIONS =================================================================*/
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Relese allocated memory
|
||
|
|
*
|
||
|
|
* Return 0 upon success, 1 otherwise and set errno
|
||
|
|
*/
|
||
|
|
int dq_free(struct duplex_queue *dq)
|
||
|
|
{
|
||
|
|
/* STEPS
|
||
|
|
* 1: Validate inputs
|
||
|
|
* 2: Free data buffer
|
||
|
|
* 3: Free ring buffer pointer
|
||
|
|
*/
|
||
|
|
if (dq == NULL) {
|
||
|
|
errno = EINVAL;
|
||
|
|
goto end;
|
||
|
|
}
|
||
|
|
|
||
|
|
pq_free(dq->tx);
|
||
|
|
pq_free(dq->rx);
|
||
|
|
free(dq->data);
|
||
|
|
free(dq);
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
|
||
|
|
end:
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Create and initialize a duplex queue
|
||
|
|
* Param:
|
||
|
|
* count : This is the number of buffer entries in each direction of the queue pair
|
||
|
|
*
|
||
|
|
* Returns a pointer to a struct duplex_queue upon success. Upon error, returns NULL and sets errno
|
||
|
|
*/
|
||
|
|
struct duplex_queue *dq_init(size_t count, size_t obj_size)
|
||
|
|
{
|
||
|
|
struct duplex_queue *dq;
|
||
|
|
|
||
|
|
/* STEPS
|
||
|
|
* 1. Validate inputs
|
||
|
|
* 2. Allocate memory for duplex_queue struct
|
||
|
|
* 3. Init the rx and tx ptr_queues
|
||
|
|
* 4. Allocate memory for data buffers
|
||
|
|
* 5: Add pointers into rx queue
|
||
|
|
*/
|
||
|
|
|
||
|
|
// STEP 1. Validate inputs
|
||
|
|
if ( (count == 0) || (obj_size == 0) ) {
|
||
|
|
errno = EINVAL;
|
||
|
|
goto end;
|
||
|
|
}
|
||
|
|
|
||
|
|
// STEP 2. Allocate memory for duplex_queue struct
|
||
|
|
dq = (struct duplex_queue*) malloc (sizeof(struct duplex_queue));
|
||
|
|
if (dq == 0) {
|
||
|
|
errno = ENOMEM;
|
||
|
|
goto end;
|
||
|
|
}
|
||
|
|
memset(dq, 0, sizeof(struct duplex_queue));
|
||
|
|
|
||
|
|
dq->count = count;
|
||
|
|
dq->obj_size = obj_size;
|
||
|
|
|
||
|
|
// STEP 3. Init the rx and tx ptr_queues
|
||
|
|
dq->rx = pq_init(count, 0);
|
||
|
|
dq->tx = pq_init(count, 0);
|
||
|
|
|
||
|
|
// STEP 4. Allocate memory for data buffer
|
||
|
|
dq->data = (__u8*) malloc (count * obj_size);
|
||
|
|
if (dq->data == 0) {
|
||
|
|
errno = ENOMEM;
|
||
|
|
goto end_free;;
|
||
|
|
}
|
||
|
|
memset(dq->data, 0, count * obj_size);
|
||
|
|
|
||
|
|
// STEP 5: Add pointers into rx queue
|
||
|
|
for ( size_t i = 0 ; i < count ; i++ )
|
||
|
|
pq_push(dq->rx, &dq->data[i*obj_size]);
|
||
|
|
|
||
|
|
return dq;
|
||
|
|
|
||
|
|
end_free:
|
||
|
|
dq_free(dq);
|
||
|
|
|
||
|
|
end:
|
||
|
|
return NULL;
|
||
|
|
}
|
||
|
|
|