summaryrefslogtreecommitdiffstats
path: root/04_exercise/threadpool.h
diff options
context:
space:
mode:
Diffstat (limited to '04_exercise/threadpool.h')
-rw-r--r--04_exercise/threadpool.h72
1 files changed, 40 insertions, 32 deletions
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