Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Garic152 committed Jun 25, 2024
1 parent be9794d commit 5374c89
Show file tree
Hide file tree
Showing 24 changed files with 1,532 additions and 52 deletions.
19 changes: 19 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: test

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
build:
name: Test Suite
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v4
- name: Install Dependencies
run: sudo apt-get update; sudo apt-get install --no-install-recommends clang make
- name: Run Tests
run: ./test.sh
54 changes: 2 additions & 52 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,52 +1,2 @@
# Prerequisites
*.d

# Object files
*.o
*.ko
*.obj
*.elf

# Linker output
*.ilk
*.map
*.exp

# Precompiled Headers
*.gch
*.pch

# Libraries
*.lib
*.a
*.la
*.lo

# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib

# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex

# Debug files
*.dSYM/
*.su
*.idb
*.pdb

# Kernel Module Compile Results
*.mod*
*.cmd
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf
*.dSYM
build/
56 changes: 56 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# the executables will be built in the "build" directory.
# the executables can be run in a terminal/shell
# cmd: ./pathto/executable
# for tests where files have to be passed as arguments
# cmd: ./pathto/executable pathto/file1 pathto/file2

# Directories
SRC_DIR = src
TEST_DIR = test
TEST_SUBDIRS = $(shell find $(TEST_DIR) -type d)
INCLUDE_DIR = include
BUILD_DIR = build

# Source files
SRCS = $(wildcard $(SRC_DIR)/*.c)
TEST_SRCS = $(foreach dir, $(TEST_SUBDIRS), $(wildcard $(dir)/*.c))

# Object files
OBJS = $(patsubst $(SRC_DIR)/%.c, $(BUILD_DIR)/%.o, $(SRCS))

# Target
TEST_TARGET = $(foreach test_src, $(TEST_SRCS), $(patsubst $(TEST_DIR)/%.c, $(BUILD_DIR)/%, $(test_src)))

# Compiler
CC = clang

# Compiler flags
CFLAGS = -Wall -Wextra -I$(INCLUDE_DIR) -pthread -g -gdwarf-4

# Default rule
all: $(TEST_TARGET)

# Rule for compiling test source files into test targets
$(BUILD_DIR)/%: $(TEST_DIR)/%.c $(OBJS) | $(BUILD_DIR)
$(CC) $(CFLAGS) $(OBJS) $< -o $@

# Rule for compiling source files into object files
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c | $(BUILD_DIR)
$(CC) $(CFLAGS) -c $< -o $@

# Create build directory if it doesn't exist
$(BUILD_DIR):
mkdir -p $(BUILD_DIR)

# Create build subsdirectories if they don't exist
$(foreach dir, $(TEST_SUBDIRS), $(shell mkdir -p $(patsubst $(TEST_DIR)/%, $(BUILD_DIR)/%, $(dir))))

# Clean up
clean:
rm -rf $(BUILD_DIR)

.PHONY: all clean

.PHONY: pack
pack:
zip -r submission.zip src/
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# README

## Lock-free Ringbuffer

This is a thread-safe implementation of the lock-free ringbuffer introduced by the following guide: https://ferrous-systems.com/blog/lock-free-ring-buffer/.

## Compilation

Use the make command to compile the project. The executable(s) will be placed in the build directory.
For the daemon, you can use the 'rndtxt.txt' files, and comprare them against the 'rndtxt_lsg.txt' files in the 'test' directory, to see if the daemon works correctly.
24 changes: 24 additions & 0 deletions include/daemon.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#ifndef DAEMON_H
#define DAEMON_H

typedef struct {
int from;
int to;
char* filename;
} connection_t;

#define MESSAGE_SIZE 128
#define MINIMUM_PORT 0 /* this will always be 0 */
#define MAXIMUM_PORT 128
#define NUMBER_OF_PROCESSING_THREADS 4

/**
* @brief simpledaemon
*
* @param connections
* @param number_of_connections
* @return int
*/
int simpledaemon(connection_t *connections, int number_of_connections);

#endif
67 changes: 67 additions & 0 deletions include/ringbuf.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#ifndef RINGBUF_H
#define RINGBUF_H

#include <stdint.h>
#include <stdlib.h>
#include <pthread.h>
#include <assert.h>
#include <string.h>
#include <time.h>
#include <errno.h>

#define SUCCESS 0
#define RINGBUFFER_FULL 1
#define RINGBUFFER_EMPTY 2
#define OUTPUT_BUFFER_TOO_SMALL 3

#define RBUF_TIMEOUT 1

typedef struct {
uint8_t* read;
uint8_t* write;
uint8_t* begin;
uint8_t* end; //1 step AFTER the last readable address
pthread_mutex_t mutex_read;
pthread_mutex_t mutex_write;
pthread_cond_t signal_read;
pthread_cond_t signal_write;
} rbctx_t;

/**
* Initialize a thread-safe lock-free ringbuffer.
* Generate ringbuffer context and memory before initialization.
*
* @param context ringbuffer context.
* @param buffer_location the first byte location of the ringbuffer in memory
* @param buffer_size size of the ringbuffer (and memory)
*/
void ringbuffer_init(rbctx_t *context, void *buffer_location, size_t buffer_size);

/**
* Write to the ringbuffer.
*
* @param context ringbuffer context
* @param message The message to be placed in the ringbuffer
* @param message_len size of the message
* @return SUCESS on succes, RINGBUFFER_FULL when message doesn't fit
*/
int ringbuffer_write(rbctx_t *context, void *message, size_t message_len);

/**
* Read from the ringbuffer.
*
* @param context ringbuffer context
* @param buffer reads to this location
* @param buffer_len_ptr size of the message buffer. Size of message received from ringbuffer is stored here
* @return SUCCESS on succes, RINGBUFFER_EMPTY if no data to read, OUTPUT_BUFFER_TOO_SMALL when read message doesn't fit
*/
int ringbuffer_read(rbctx_t *context, void *buffer, size_t *buffer_len_ptr);

/**
* Frees all memory allocated and syncronization variables created during initialization.
*
* @param context ringbuffer context
*/
void ringbuffer_destroy(rbctx_t *context);

#endif //RINGBUF_H
Loading

0 comments on commit 5374c89

Please sign in to comment.