commit 075196fcb6ac71098ef82a9f277b2e760347f1ee Author: nikto_b Date: Tue Jan 21 19:15:22 2025 +0300 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..80cb078 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +out +.ccls-cache +.vscode +compile_commands.json diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5d44abb --- /dev/null +++ b/Makefile @@ -0,0 +1,97 @@ +BUILD_DIR=out +SRC_DIR=src +INC_DIR=inc +CC=gcc +AR=ar +OBJDUMP=objdump +LIBS= +LIBS_HEADERS=deps/ +STANDART=c23 +OPTIMIZE=-Og +TARGET=ptQueue + + +DEFINES=#-DOPCODE_WORDSIZE=2 -DMEM_CELL_WORDS=1 -DPC_WORDSIZE=2 -DGP_REG_CELL_WORDS=1 -DIO_REG_CELL_WORDS=1 + +C_SOURCES=$(wildcard $(SRC_DIR)/*.c) +# C_SOURCES=$(wildcard $(SRC_DIR)/*.c) +C_HEADERS=$(wildcard $(INC_DIR)/*.h) + +C_INCLUDES=-I$(INC_DIR)/ $(addprefix -I,$(LIBS_HEADERS)) + +C_DEFS=-D_POSIX_C_SOURCE=199309L + +DISABLE_FLAGS=-Wno-unused-variable -Wno-unused-parameter -Wno-write-strings -Wno-pointer-arith +PEDANTIC_FLAGS=-pedantic -pedantic-errors $(DISABLE_FLAGS) -Wall -Wcast-align -Wcast-qual -Wconversion -Wduplicated-branches -Wduplicated-cond -Werror -Wextra -Wfloat-equal -Wlogical-op -Wpedantic -Wredundant-decls -Wsign-conversion +ANALYZER_FLAGS=-fanalyzer -fdiagnostics-show-option -fdiagnostics-color=always +LSECTIONS=-ffunction-sections -fdata-sections -Wl,--gc-sections +CFLAGS=$(C_DEFS) -g $(C_INCLUDES) $(DEFINES) $(OPTIMIZE) --std=$(STANDART) $(PEDANTIC_FLAGS) $(ANALYZER_FLAGS) +LFLAGS=$(OPTIMIZE) -g $(PEDANTIC_FLAGS) $(DEFINES) -flto -fuse-linker-plugin $(LSECTIONS) -lm + + + +OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o))) $(LIBS) +vpath %.c $(sort $(dir $(C_SOURCES))) +vpath %.h $(sort $(dir $(C_HEADERS))) + +# $(info SOURCES=$(C_SOURCES)) +# $(info HEADERS=$(C_HEADERS)) +# $(info OBJECTS=$(OBJECTS)) + + +all: build + +build: date deps Dir $(C_HEADERS) target compile_commands + +rebuild: clean | build + + + + + +target: date $(BUILD_DIR)/$(TARGET).a + + +$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) + @echo -e '\033[1;32mCC\t'$<'\t->\t'$@'\033[0m' + @$(CC) -c $(CFLAGS) $< -o $@ + + +$(BUILD_DIR)/main.elf: $(OBJECTS) + @echo -e '\033[1;32mELF\t'$(OBJECTS)'\n\t\t\t->\t'$@'\033[0m' + @$(CC) $(LFLAGS) $(OBJECTS) -o $(BUILD_DIR)/main.elf + + +$(BUILD_DIR)/$(TARGET).a: $(BUILD_DIR)/ptQueue.o + @echo -e '\033[1;32mAR\t'$(BUILD_DIR)/$(TARGET).o'\n\t\t\t->\t'$@'\033[0m' + @$(AR) rcs $(BUILD_DIR)/$(TARGET).a $(BUILD_DIR)/$(TARGET).o + + + +BuildDir: + @mkdir -p $(BUILD_DIR) + +SrcDir: + @mkdir -p $(SRC_DIR) + +IncDir: + @mkdir -p $(INC_DIR) + +Dir: BuildDir SrcDir IncDir + + +.PHONY: clean deps +clean: + @rm -rf $(BUILD_DIR)/* +# @rm -f compile_commands.json + @echo -e '\033[0;31mCleaned\033[0m' + +.NOTPARALLEL: date target rebuild deps +date: + @echo -e '\033[1;32m'"Starting building $(TARGET) at " | tr -d '\n' + @date + @echo -e '\033[0m' + + +compile_commands: +# @bear -- ./.gen_compile_commands.sh $(TARGET) $(CC) "$(CFLAGS)" "$(LFLAGS)" "$(OBJECTS)" diff --git a/inc/ptQueue.h b/inc/ptQueue.h new file mode 100644 index 0000000..fc322ec --- /dev/null +++ b/inc/ptQueue.h @@ -0,0 +1,20 @@ +#ifndef __PT_QUEUE_H__ +#define __PT_QUEUE_H__ + +typedef struct ptQueueElem { + _Atomic(struct ptQueueElem*) nextEl; + _Atomic(void*) payload; +} ptQueueElem; + + +typedef struct { + _Atomic(ptQueueElem*) head; + _Atomic(ptQueueElem*) tail; +} ptQueue; + + +int ptQueuePush(ptQueue* q, void* payload, char* errbuf); +ptQueue* ptQueueCreate(char* errbuf); +void ptQueueFree(ptQueue* q); + +#endif //ifndef __PT_QUEUE_H__ \ No newline at end of file diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..ee8442e --- /dev/null +++ b/src/main.c @@ -0,0 +1,203 @@ +#include +#include +#include +#include +#include +#include + +#include +#include + + +#include + +#include + +#include "ptQueue.h" + + +void *threadMain(void *param); + + + +void microsecond_sleep(int microseconds) { + struct timespec ts; + ts.tv_sec = microseconds / 1000000; + ts.tv_nsec = (microseconds % 1000000) * 1000; + nanosleep(&ts, NULL); +} + +int main(int argc, char** argv) +{ + + pthread_t tid; + pthread_attr_t attr; + + char errbuf[1024]; + + + ptQueue* qOut = ptQueueCreate(errbuf); + if(qOut == NULL) + { + printf("Failed to create out q: %s\n", errbuf); + abort(); + } + ptQueue* qIn = ptQueueCreate(errbuf); + if(qIn == NULL) + { + printf("Failed to create out q: %s\n", errbuf); + abort(); + } + + ptQueue** ptArgs = malloc(sizeof(ptQueue*) * 2); + if(ptArgs == NULL) + { + abort(); + } + ptArgs[0] = qOut; + ptArgs[1] = qIn; + + pthread_attr_init(&attr); + pthread_create(&tid, &attr, threadMain, ptArgs); + + + for(int i = 1; i < 4096; i++) + { + int* pass = malloc(sizeof(int)); + if(pass == NULL) + { + abort(); + } + *pass = i; + + int excode = ptQueuePush(qOut, pass, errbuf); + if(excode) + { + printf("Unable to push: %s\n", errbuf); + abort(); + } + } + + int* ii = malloc(sizeof(int)); + if(ii == NULL) + { + abort(); + } + *ii = 0; + + int excode = ptQueuePush(qOut, ii, errbuf); + if(excode) + { + printf("Unable to push 0: %s\n", errbuf); + abort(); + } + + ptQueueElem* tailIn = qIn->tail; + + while (1) + { + void* payload = atomic_load(&(tailIn->payload)); + if(payload == NULL) + { + microsecond_sleep(100); + continue; + } + int* code = payload; + + printf("nextEl)); + if (newTail == NULL) + { + abort(); + } + free(tailIn); + tailIn = newTail; + } + + pthread_join(tid, NULL); + return 0; +} + + + +void *threadMain(void *param) +{ + ptQueue** params = param; + ptQueue* qIn = params[0]; + ptQueue* qOut = params[1]; + ptQueueElem* tailIn = atomic_load(&(qIn->head)); + char errbuf[1024]; + + while (1) + { + void* payload = atomic_load(&(tailIn->payload)); + if(payload == NULL) + { + microsecond_sleep(100); + continue; + } + int* code = payload; + + printf(">Done reading %d\n", *code); + + + int* pass = malloc(sizeof(int)); + if(pass != NULL) + { + *pass = *code; + ptQueuePush(qOut, pass, errbuf); + } + + if(*code == 0) + { + free(payload); + break; + } + free(payload); + ptQueueElem* newTail = atomic_load(&(tailIn->nextEl)); + if (newTail == NULL) + { + abort(); + } + free(tailIn); + tailIn = newTail; + + } + + for(int i = 4096; i >= 0; i--) + { + int* pass = malloc(sizeof(int)); + if(pass == NULL) + { + continue; + } + *pass = i; + int excode = ptQueuePush(qOut, pass, errbuf); + if(excode != 0) + { + printf("failed to push: %s\n", errbuf); + abort(); + } + } + + pthread_exit(0); +} diff --git a/src/ptQueue.c b/src/ptQueue.c new file mode 100644 index 0000000..bc6220b --- /dev/null +++ b/src/ptQueue.c @@ -0,0 +1,83 @@ +#include +#include +#include +#include + +#include "ptQueue.h" + + + +int ptQueuePush(ptQueue* q, void* payload, char* errbuf) +{ + _Atomic(ptQueueElem*) tail = atomic_load(&q->tail); + + + ptQueueElem* newNode = (ptQueueElem*)malloc(sizeof(ptQueue)); + if(newNode == NULL) + { + sprintf(errbuf, "unable to allocate new node"); + return 1; + } + newNode->payload = NULL; + newNode->nextEl = NULL; + + q->tail = newNode; + + ptQueueElem* oldNext = atomic_load(&tail->nextEl); + + do { + tail->nextEl = newNode; + } while (!atomic_compare_exchange_weak(&tail->nextEl, &oldNext, newNode)); + + + void* oldPayload = atomic_load(&tail->payload); + + do { + tail->payload = payload; + } while (!atomic_compare_exchange_weak(&tail->payload, &oldPayload, payload)); + return 0; +} + + +ptQueue* ptQueueCreate(char* errbuf) +{ + ptQueue* q = malloc(sizeof(ptQueue)); + if(q == NULL) + { + sprintf(errbuf, "unable to allocate queue struct"); + return NULL; + } + ptQueueElem* baseElm = malloc(sizeof(ptQueueElem)); + if(baseElm == NULL) + { + sprintf(errbuf, "unable to allocate first queue elem"); + free(q); + return NULL; + } + baseElm->nextEl = NULL; + baseElm->payload = NULL; + q->head = baseElm; + q->tail = baseElm; + + return q; +} + +void ptQueueFree(ptQueue* q) +{ + if(q == NULL) + { + return; + } + ptQueueElem* head = q->head; + while(head != NULL) + { + ptQueueElem* newHead = head->nextEl; + if(head->payload != NULL) + { + free(head->payload); + } + free(head); + head = newHead; + } + free(q); +} \ No newline at end of file