From fa0e0fa5e68ad1f8f31bb44926cd1a6df4e20d78 Mon Sep 17 00:00:00 2001 From: Niklas Halle Date: Sat, 20 Jun 2020 12:31:49 +0200 Subject: ppm tests --- 04_exercise/ppmlib/main.c | 3 + 04_exercise/ppmlib/main.out.c | 166 ++++++++++++++++++++++++++++++++++++++++++ 04_exercise/threadpool.h | 72 ++++++++++-------- 3 files changed, 209 insertions(+), 32 deletions(-) create mode 100644 04_exercise/ppmlib/main.c create mode 100644 04_exercise/ppmlib/main.out.c diff --git a/04_exercise/ppmlib/main.c b/04_exercise/ppmlib/main.c new file mode 100644 index 0000000..cd1c21e --- /dev/null +++ b/04_exercise/ppmlib/main.c @@ -0,0 +1,3 @@ +#include "../threadpool.h" + +TASK(int, test_func, int) diff --git a/04_exercise/ppmlib/main.out.c b/04_exercise/ppmlib/main.out.c new file mode 100644 index 0000000..5a0bcf1 --- /dev/null +++ b/04_exercise/ppmlib/main.out.c @@ -0,0 +1,166 @@ +# 1 "main.c" +# 1 "" +# 1 "" +# 31 "" +# 1 "/usr/include/stdc-predef.h" 1 3 4 +# 32 "" 2 +# 1 "main.c" +# 1 "../threadpool.h" 1 + + + +# 1 "/usr/lib/gcc/x86_64-pc-linux-gnu/10.1.0/include/stdatomic.h" 1 3 4 +# 29 "/usr/lib/gcc/x86_64-pc-linux-gnu/10.1.0/include/stdatomic.h" 3 4 + +# 29 "/usr/lib/gcc/x86_64-pc-linux-gnu/10.1.0/include/stdatomic.h" 3 4 +typedef enum { + memory_order_relaxed = 0, + memory_order_consume = 1, + memory_order_acquire = 2, + memory_order_release = 3, + memory_order_acq_rel = 4, + memory_order_seq_cst = 5 +} memory_order; + + +typedef _Atomic _Bool atomic_bool; +typedef _Atomic char atomic_char; +typedef _Atomic signed char atomic_schar; +typedef _Atomic unsigned char atomic_uchar; +typedef _Atomic short atomic_short; +typedef _Atomic unsigned short atomic_ushort; +typedef _Atomic int atomic_int; +typedef _Atomic unsigned int atomic_uint; +typedef _Atomic long atomic_long; +typedef _Atomic unsigned long atomic_ulong; +typedef _Atomic long long atomic_llong; +typedef _Atomic unsigned long long atomic_ullong; +typedef _Atomic short unsigned int atomic_char16_t; +typedef _Atomic unsigned int atomic_char32_t; +typedef _Atomic int atomic_wchar_t; +typedef _Atomic signed char atomic_int_least8_t; +typedef _Atomic unsigned char atomic_uint_least8_t; +typedef _Atomic short int atomic_int_least16_t; +typedef _Atomic short unsigned int atomic_uint_least16_t; +typedef _Atomic int atomic_int_least32_t; +typedef _Atomic unsigned int atomic_uint_least32_t; +typedef _Atomic long int atomic_int_least64_t; +typedef _Atomic long unsigned int atomic_uint_least64_t; +typedef _Atomic signed char atomic_int_fast8_t; +typedef _Atomic unsigned char atomic_uint_fast8_t; +typedef _Atomic long int atomic_int_fast16_t; +typedef _Atomic long unsigned int atomic_uint_fast16_t; +typedef _Atomic long int atomic_int_fast32_t; +typedef _Atomic long unsigned int atomic_uint_fast32_t; +typedef _Atomic long int atomic_int_fast64_t; +typedef _Atomic long unsigned int atomic_uint_fast64_t; +typedef _Atomic long int atomic_intptr_t; +typedef _Atomic long unsigned int atomic_uintptr_t; +typedef _Atomic long unsigned int atomic_size_t; +typedef _Atomic long int atomic_ptrdiff_t; +typedef _Atomic long int atomic_intmax_t; +typedef _Atomic long unsigned int atomic_uintmax_t; +# 92 "/usr/lib/gcc/x86_64-pc-linux-gnu/10.1.0/include/stdatomic.h" 3 4 + +extern void atomic_thread_fence(memory_order); + +extern void atomic_signal_fence(memory_order); + +# 218 "/usr/lib/gcc/x86_64-pc-linux-gnu/10.1.0/include/stdatomic.h" 3 4 +typedef _Atomic struct { + + _Bool __val; + + +} atomic_flag; + + +extern _Bool atomic_flag_test_and_set(volatile atomic_flag *); + + +extern _Bool atomic_flag_test_and_set_explicit(volatile atomic_flag *, + memory_order); + + +extern void atomic_flag_clear(volatile atomic_flag *); + +extern void atomic_flag_clear_explicit(volatile atomic_flag *, memory_order); + +# 5 "../threadpool.h" 2 +# 1 "/usr/lib/gcc/x86_64-pc-linux-gnu/10.1.0/include/stddef.h" 1 3 4 +# 143 "/usr/lib/gcc/x86_64-pc-linux-gnu/10.1.0/include/stddef.h" 3 4 +typedef long int ptrdiff_t; +# 209 "/usr/lib/gcc/x86_64-pc-linux-gnu/10.1.0/include/stddef.h" 3 4 +typedef long unsigned int size_t; +# 321 "/usr/lib/gcc/x86_64-pc-linux-gnu/10.1.0/include/stddef.h" 3 4 +typedef int wchar_t; +# 415 "/usr/lib/gcc/x86_64-pc-linux-gnu/10.1.0/include/stddef.h" 3 4 +typedef struct { + long long __max_align_ll __attribute__((__aligned__(__alignof__(long long)))); + long double __max_align_ld __attribute__((__aligned__(__alignof__(long double)))); +# 426 "/usr/lib/gcc/x86_64-pc-linux-gnu/10.1.0/include/stddef.h" 3 4 +} max_align_t; +# 6 "../threadpool.h" 2 +# 1 "../ppmlib/ppmlib.h" 1 +# 16 "../ppmlib/ppmlib.h" +# 1 "/usr/lib/gcc/x86_64-pc-linux-gnu/10.1.0/include/stddef.h" 1 3 4 +# 17 "../ppmlib/ppmlib.h" 2 +# 7 "../threadpool.h" 2 + + + + + + + +# 13 "../threadpool.h" + +typedef void (*ThreadTask_f)(void *); + +typedef atomic_char FutureStatus; +enum FurutureStatusEnum { + FUT_WAITING = 0, FUT_IN_PROGRESS = 1, FUT_DONE = 2 +}; + + +typedef struct Future { + ThreadTask_f fn; + + FutureStatus status; +} Future; +# 33 "../threadpool.h" + +extern int tpInit(size_t size); + + +extern void tpRelease(void); + +# 52 "../threadpool.h" + +extern void tpAsync(Future *future); + +# 63 "../threadpool.h" + +extern void tpAwait(Future *future); + +# 2 "main.c" 2 + +int test_func(int); + +typedef struct { + Future fut; + int int_3; + int res; +} test_func_fut; + +static void test_funcThunk(void *args) { + test_func_fut *data = args; + data->res = test_func(data->int_3); +} + +static inline test_func_fut test_funcFuture( + int int_3) { return (test_func_fut) {.fut = {.fn = &test_funcThunk, .status=FUT_WAITING}, .int_3 = int_3}; } + +static inline test_func_fut *test_funcAsync(test_func_fut *future) { return tpAsync(&future->fut), future; } + +static inline int test_funcAwait(test_func_fut *future) { return tpAwait(&future->fut), future->res; } diff --git a/04_exercise/threadpool.h b/04_exercise/threadpool.h index 745c4dd..5ffefdf 100644 --- a/04_exercise/threadpool.h +++ b/04_exercise/threadpool.h @@ -3,24 +3,26 @@ #include #include -#include +#include "ppmlib/ppmlib.h" /**@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 void (*ThreadTask_f)(void *); typedef atomic_char FutureStatus; -enum FurutureStatusEnum { FUT_WAITING = 0, FUT_IN_PROGRESS=1, FUT_DONE = 2}; +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; + 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. * @@ -92,30 +94,36 @@ extern void tpAwait(Future *future); * @param NAME Name der Funktion * @param ARG Parametertyp der Funktion */ -#define TASK(TYPE, NAME, ARG) \ - TYPE NAME(ARG); \ - \ - typedef struct { \ - Future fut; \ - ARG arg; \ - TYPE res; \ - } NAME ## _fut; \ - \ - static void NAME ## Thunk(void *args) { \ - NAME ## _fut *data = args; \ - data->res = NAME(data->arg); \ - } \ - static inline NAME ## _fut NAME ## Future(ARG arg) { \ - return (NAME ## _fut) { \ - .fut = { .fn = &NAME ## Thunk, .status=FUT_WAITING}, \ - .arg = arg \ - }; \ - } \ - static inline NAME ## _fut* NAME ## Async(NAME ## _fut *future) { \ - return tpAsync(&future->fut), future; \ - } \ - static inline TYPE NAME ## Await(NAME ## _fut *future) { \ - return tpAwait(&future->fut), future->res; \ - } +#define DECL_ARG(ARG) ARG UID(ARG); +#define DO_NOTHING(ARG) ARG +#define POINT_ARG(ARG) data->UID(ARG) +#define AWAIT_ARG(ARG) ARG UID(ARG) +#define ASSIGN_ARG(ARG) .UID(ARG) = UID(ARG) +#define APPEND_COMMA(ARG) ARG, +#define TASK(TYPE, NAME, ...) \ + TYPE NAME(__VA_ARGS__); \ + \ + typedef struct { \ + Future fut; \ + FOREACH(DO_NOTHING,DECL_ARG,(__VA_ARGS__)) \ + TYPE res; \ + } NAME ## _fut; \ + \ + static void NAME ## Thunk(void *args) { \ + NAME ## _fut *data = args; \ + data->res = NAME(FOREACH(APPEND_COMMA,POINT_ARG,(__VA_ARGS__))); \ + } \ + static inline NAME ## _fut NAME ## Future(FOREACH(APPEND_COMMA,AWAIT_ARG,(__VA_ARGS__))) { \ + return (NAME ## _fut) { \ + .fut = { .fn = &NAME ## Thunk, .status=FUT_WAITING}, \ + FOREACH(APPEND_COMMA,ASSIGN_ARG,(__VA_ARGS__)) \ + }; \ + } \ + static inline NAME ## _fut* NAME ## Async(NAME ## _fut *future) { \ + return tpAsync(&future->fut), future; \ + } \ + static inline TYPE NAME ## Await(NAME ## _fut *future) { \ + return tpAwait(&future->fut), future->res; \ + } #endif -- cgit v1.2.3-54-g00ecf