summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNiklas Halle <niklas@niklashalle.net>2020-06-20 12:31:49 +0200
committerNiklas Halle <niklas@niklashalle.net>2020-06-20 12:31:49 +0200
commitfa0e0fa5e68ad1f8f31bb44926cd1a6df4e20d78 (patch)
tree706a88881ed9e73d08fb3a356e0c6eb0ba1570b2
parent021afcb8e4aa4fbc7905f527089c415108c86c75 (diff)
downloadbetriebssysteme-dev/niklas.tar.gz
betriebssysteme-dev/niklas.zip
ppm testsdev/niklas
-rw-r--r--04_exercise/ppmlib/main.c3
-rw-r--r--04_exercise/ppmlib/main.out.c166
-rw-r--r--04_exercise/threadpool.h72
3 files changed, 209 insertions, 32 deletions
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 "<built-in>"
+# 1 "<command-line>"
+# 31 "<command-line>"
+# 1 "/usr/include/stdc-predef.h" 1 3 4
+# 32 "<command-line>" 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 <stdatomic.h>
#include <stddef.h>
-#include <ppmlib.h>
+#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