Release candidate
This commit is contained in:
parent
c8cae5055a
commit
d6e467c7c4
52
Makefile
Normal file
52
Makefile
Normal file
@ -0,0 +1,52 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# ******************************************************************************
|
||||
#
|
||||
# @file Makefile
|
||||
#
|
||||
# @brief Makefile for Duplex Queue library
|
||||
#
|
||||
# @copyright Copyright (C) 2024 Jackrabbit Founders LLC. All rights reserved.
|
||||
#
|
||||
# @date Mar 2024
|
||||
# @author Barrett Edwards <code@jrlabs.io>
|
||||
#
|
||||
# ******************************************************************************
|
||||
|
||||
CC=gcc
|
||||
CFLAGS= -g3 -O0 -Wall -Wextra
|
||||
MACROS=
|
||||
INCLUDE_DIR=/usr/local/include
|
||||
LIB_DIR=/usr/local/lib
|
||||
INCLUDE_PATH=-I $(INCLUDE_DIR)
|
||||
LIB_PATH=-L $(LIB_DIR)
|
||||
LIBS=-l ptrqueue
|
||||
TARGET=duplexqueue
|
||||
|
||||
all: testbench lib$(TARGET).a
|
||||
|
||||
testbench: testbench.c main.o
|
||||
$(CC) $^ $(CFLAGS) $(MACROS) $(INCLUDE_PATH) $(LIB_PATH) $(LIBS) -o $@
|
||||
|
||||
lib$(TARGET).a: main.o
|
||||
ar rcs $@ $^
|
||||
|
||||
main.o: main.c main.h
|
||||
$(CC) -c $< $(CFLAGS) $(MACROS) $(INCLUDE_PATH) -o $@
|
||||
|
||||
clean:
|
||||
rm -rf ./*.o ./*.a testbench
|
||||
|
||||
doc:
|
||||
doxygen
|
||||
|
||||
install: lib$(TARGET).a
|
||||
sudo cp lib$(TARGET).a $(LIB_DIR)/
|
||||
sudo cp main.h $(INCLUDE_DIR)/$(TARGET).h
|
||||
|
||||
.PHONY: all clean doc install
|
||||
|
||||
# Variables
|
||||
# $^ Will expand to be all the sensitivity list
|
||||
# $< Will expand to be the frist file in sensitivity list
|
||||
# $@ Will expand to be the target name (the left side of the ":" )
|
||||
# -c gcc will compile but not try and link
|
||||
142
main.c
Normal file
142
main.c
Normal file
@ -0,0 +1,142 @@
|
||||
/* 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;
|
||||
}
|
||||
|
||||
47
main.h
Normal file
47
main.h
Normal file
@ -0,0 +1,47 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0 */
|
||||
/**
|
||||
* @file duplexqueue.h
|
||||
*
|
||||
* @brief Header file for Duplex Queue library
|
||||
*
|
||||
* @copyright Copyright (C) 2024 Jackrabbit Founders LLC. All rights reserved.
|
||||
*
|
||||
* @date Feb 2024
|
||||
* @author Barrett Edwards <code@jrlabs.io>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _DUPLEXQUEUE_H
|
||||
#define _DUPLEXQUEUE_H
|
||||
|
||||
/* INCLUDES ==================================================================*/
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <ptrqueue.h>
|
||||
|
||||
/* MACROS ====================================================================*/
|
||||
|
||||
/* ENUMERATIONS ==============================================================*/
|
||||
|
||||
/* STRUCTS ===================================================================*/
|
||||
|
||||
/**
|
||||
* Opaque data structure
|
||||
*/
|
||||
struct duplex_queue {
|
||||
struct ptr_queue *tx;
|
||||
struct ptr_queue *rx;
|
||||
__u8 *data;
|
||||
size_t count;
|
||||
size_t obj_size;
|
||||
};
|
||||
|
||||
/* GLOBAL VARIABLES ==========================================================*/
|
||||
|
||||
/* PROTOTYPES ================================================================*/
|
||||
|
||||
int dq_free(struct duplex_queue *pq);
|
||||
struct duplex_queue *dq_init(size_t count, size_t obj_size);
|
||||
|
||||
#endif /* ifndef _DUPLEXQUEUE_H */
|
||||
119
testbench.c
Normal file
119
testbench.c
Normal file
@ -0,0 +1,119 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0 */
|
||||
/**
|
||||
* @file textbench.c
|
||||
*
|
||||
* @brief Testbench 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 ==================================================================*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <ptrqueue.h>
|
||||
|
||||
#include "duplexqueue.h"
|
||||
|
||||
/* MACROS ====================================================================*/
|
||||
|
||||
#define QUEUE_CAPACITY 10
|
||||
#define ITERATIONS 10000
|
||||
|
||||
/* ENUMERATIONS ==============================================================*/
|
||||
|
||||
/* STRUCTS ===================================================================*/
|
||||
|
||||
/* GLOBAL VARIABLES ==========================================================*/
|
||||
|
||||
/* PROTOTYPES ================================================================*/
|
||||
|
||||
|
||||
void *consumer(void *arg)
|
||||
{
|
||||
struct duplex_queue *dq;
|
||||
void *ptr;
|
||||
int rv;
|
||||
|
||||
dq = (struct duplex_queue*) arg;
|
||||
|
||||
printf("%s started \n", __FUNCTION__);
|
||||
|
||||
for ( __u64 i = 0 ; i < ITERATIONS ; i++ ) {
|
||||
ptr = pq_pop(dq->tx, 1);
|
||||
rv = pq_push(dq->rx, ptr);
|
||||
printf("%s pushed on to rx queue val:%p rv:%d\n", __FUNCTION__, ptr, rv);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *producer(void *arg)
|
||||
{
|
||||
struct duplex_queue *dq;
|
||||
int rv;
|
||||
void *ptr;
|
||||
|
||||
dq = (struct duplex_queue*) arg;
|
||||
|
||||
printf("%s started \n", __FUNCTION__);
|
||||
|
||||
for ( __u64 i = 0 ; i < ITERATIONS ; i++ ) {
|
||||
ptr = pq_pop(dq->rx, 1);
|
||||
rv = pq_push(dq->tx, ptr);
|
||||
printf("%s pushed on to tx queue val:%p rv:%d\n", __FUNCTION__, ptr, rv);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void threads(struct duplex_queue *dq)
|
||||
{
|
||||
int rv;
|
||||
|
||||
pthread_t producer_thread;
|
||||
pthread_t consumer_thread;
|
||||
|
||||
rv = pthread_create( &consumer_thread, NULL, consumer, (void*) dq );
|
||||
if (rv != 0) {
|
||||
printf("Error creating producer thread\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
sleep(1);
|
||||
|
||||
rv = pthread_create( &producer_thread, NULL, producer, (void*) dq );
|
||||
if (rv != 0) {
|
||||
printf("Error creating producer thread\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
sleep(1);
|
||||
|
||||
printf("%s Waiting for threads to exit\n", __FUNCTION__);
|
||||
pthread_join( producer_thread, NULL);
|
||||
printf("%s joined with producer thread\n", __FUNCTION__);
|
||||
pthread_join( consumer_thread, NULL);
|
||||
printf("%s joined with consumer thread\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
struct duplex_queue *dq;
|
||||
|
||||
dq = dq_init(QUEUE_CAPACITY, 4);
|
||||
|
||||
threads(dq);
|
||||
|
||||
dq_free(dq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user