From fad28509e7463082a508b761c797773538df7d27 Mon Sep 17 00:00:00 2001 From: Stefan Zabka Date: Thu, 11 Jun 2020 01:00:32 +0200 Subject: First ideas --- 04_exercise/CMakeLists.txt | 18 +++++++++--- 04_exercise/main.c | 2 +- 04_exercise/quicksort.c | 5 ++-- 04_exercise/threadpool.c | 69 +++++++++++++++++++++++++++++++++++++++++----- 04_exercise/threadpool.h | 8 +++++- CMakeLists.txt | 2 +- 6 files changed, 88 insertions(+), 16 deletions(-) diff --git a/04_exercise/CMakeLists.txt b/04_exercise/CMakeLists.txt index 7b18fda..d8d1200 100644 --- a/04_exercise/CMakeLists.txt +++ b/04_exercise/CMakeLists.txt @@ -1,12 +1,22 @@ +set(THREADS_PREFER_PTHREAD_FLAG ON) +find_package(Threads REQUIRED) + add_executable(quicksort quicksort.c) target_link_libraries(quicksort PRIVATE threadpool) -target_compile_options(quicksort INTERFACE ${PROJECT_WARNINGS}) add_library(threadpool threadpool.c) -target_compile_options(threadpool INTERFACE ${PROJECT_WARNINGS}) -target_link_libraries(threadpool warnings) +target_link_libraries(threadpool PRIVATE array Threads::Threads arena_list) +target_link_libraries(threadpool INTERFACE warnings) + add_executable(fibonacci main.c) target_compile_options(fibonacci INTERFACE ${PROJECT_WARNINGS}) -target_link_libraries(fibonacci PRIVATE threadpool warnings) +target_link_libraries(fibonacci PRIVATE threadpool) +target_link_libraries(fibonacci INTERFACE warnings) + +add_library(arena_list arena/arena_list.c) +target_include_directories(arena_list PUBLIC arena) +target_link_libraries(arena_list INTERFACE warnings) +add_executable(arena_test arena/arena_test.c) +target_link_libraries(arena_test PRIVATE arena_list) \ No newline at end of file diff --git a/04_exercise/main.c b/04_exercise/main.c index cf03191..18fb21e 100644 --- a/04_exercise/main.c +++ b/04_exercise/main.c @@ -3,7 +3,7 @@ #include #include -static TASK(long, fib, long); +static TASK(long, fib, long) long fib(long n) { if (n <= 1) diff --git a/04_exercise/quicksort.c b/04_exercise/quicksort.c index 88a47a2..f912f2b 100644 --- a/04_exercise/quicksort.c +++ b/04_exercise/quicksort.c @@ -3,6 +3,7 @@ #include #include #include +#include static size_t partition(int v[], size_t len); @@ -87,9 +88,9 @@ int main(int argc, const char *argv[]) { /* read the length of the list from the command line */ size_t list_len = 30000000; if (argc >= 2) { - long arg = atol(argv[1]); + long arg = strtol(argv[1], (char **)&argv[strlen(argv[1])], 10); if (arg > 0) - list_len = arg; + list_len = (size_t)arg; } /* generate a list with random integers */ diff --git a/04_exercise/threadpool.c b/04_exercise/threadpool.c index 3172147..510e83e 100644 --- a/04_exercise/threadpool.c +++ b/04_exercise/threadpool.c @@ -1,23 +1,78 @@ #include "threadpool.h" +#include "arena_list.h" +#include "array.h" +#include +#include +#include #include #include -#include + +#define MAX_FUTURES 2048 +typedef struct Thread { + pthread_t pthread; + size_t index; +} Thread; typedef struct ThreadPool { - /* TODO: benötigte Attribute hinzufügen */ + /* TODO: benötigte Attribute hinzufügen */ + size_t size; + Thread *threads; + Node arena [MAX_FUTURES]; + ArenaList al; + } ThreadPool; -/* TODO: interne, globale Variablen hinzufügen */ +ThreadPool threadPool; /* TODO: interne Hilfsfunktionen hinzufügen */ +void * poolWorkerFunc(void * v_index) { + size_t index = * (size_t *) v_index; + printf("Thread %zu started", index); + return NULL; +} int tpInit(size_t size) { - return 0; + threadPool.size = size; + arrayInit(threadPool.threads); + alInit(threadPool.arena, MAX_FUTURES); + for (size_t i = 0; i < size; ++i) { + arrayPush(threadPool.threads); + int status; + threadPool.threads[i].index = i; + if ((status = pthread_create(&threadPool.threads[i].pthread, NULL, + poolWorkerFunc, &threadPool.threads[i].index)) < 0) { + return status; + } + } + return 0; } -void tpRelease(void) {} +void tpRelease(void) { + for (size_t i = 0; i < threadPool.size; ++i) { + if (pthread_cancel(threadPool.threads[i].pthread) != 0) { + perror("Thread doesn't exist anymore"); + exit(-1); + } + } + for (size_t i = 0; i < threadPool.size; ++i) { + int status; + if ((status = pthread_join(threadPool.threads[i].pthread, NULL)) != 0) { + perror("An error occured while joining the threads"); + exit(status); + } + } +} + +void tpAsync(Future *future) { + alPush(&threadPool.al, (void *) future); +} + +void tpAwait(Future *future) { + if(atomic_load(&future->status) == FUT_DONE) { + alRemoveElem(&threadPool.al, (void *) future); + return; + } +} -void tpAsync(Future *future) {} -void tpAwait(Future *future) {} diff --git a/04_exercise/threadpool.h b/04_exercise/threadpool.h index 6b758cd..1b5d64d 100644 --- a/04_exercise/threadpool.h +++ b/04_exercise/threadpool.h @@ -1,20 +1,26 @@ #ifndef THREADPOOL_H_INCLUDED #define THREADPOOL_H_INCLUDED +#include #include + + /**@brief Funktionszeiger auf eine asynchron auszuführende Funktion. - * + * * Der Parameter kann zur Übergabe von Argumenten und den Rückgabewerten * der Funktion genutzt werden. */ typedef void (*ThreadTask_f)(void*); +typedef atomic_char FutureStatus; +enum FurutureStatusEnum { FUT_WAITING = 0, FUT_IN_PROGRESS=1, FUT_DONE = 2}; /**@brief Handle zum zukünftigen Rückgabewert eines asynchronen Funktionsrufes. */ typedef struct Future { ThreadTask_f fn; ///<@brief Zeiger auf die auszuführende Funktion. /* TODO: benötigte Attribute hinzufügen */ + FutureStatus status; } Future; /**@brief Initialisiert den globalen Thread-Pool. diff --git a/CMakeLists.txt b/CMakeLists.txt index 55962c2..196567b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,6 +42,6 @@ set(GCC_WARNINGS # probably wanted ) -set(PROJECT_WARNINGS ${GCC_WARNINGS}) +set(PROJECT_WARNINGS ${CLANG_WARNINGS}) add_library(warnings INTERFACE) target_compile_options(warnings INTERFACE ${PROJECT_WARNINGS}) -- cgit v1.2.3-54-g00ecf