summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author@syxhe <https://t.me/syxhe>2025-04-17 21:32:35 -0500
committer@syxhe <https://t.me/syxhe>2025-04-17 21:32:35 -0500
commit9bd10281119a28323ddd05bd13827bceb553cc56 (patch)
tree54bd1701fe006810c7097808021505bec0c05c00
parent18811c585d5ff1285446d3eee301e2139dc1a60b (diff)
Start work on implementing a threadpool
-rw-r--r--src/threadpool.c109
-rw-r--r--src/threadpool.h13
2 files changed, 122 insertions, 0 deletions
diff --git a/src/threadpool.c b/src/threadpool.c
new file mode 100644
index 0000000..8f1cf0b
--- /dev/null
+++ b/src/threadpool.c
@@ -0,0 +1,109 @@
1#include "threadpool.h"
2#include "shared.h"
3
4#include <threads.h>
5#include <stdlib.h>
6#include <errno.h>
7
8/* Mutex: Lock a shared resource. Used to prevent race conditions when accessing / modifying some shared resource. A lock must
9// always be followed by an unlock
10
11// Semaphore: Send / wait on a signal; solves the consumer/producer problem. A function that sends should never wait, and a
12// function that waits should never send */
13
14// Pair some data with a mutex. Specifically a way to deal with mutices easier, not for data storage (mtxpair_free does not free the `(void*)data` member)
15typedef struct mtxp {
16 void *data;
17 mtx_t *mtx;
18} mtxpair;
19
20mtxpair * mtxpair_init(void * const data, int type) {
21 mtxpair *mtxp = malloc(1 * sizeof(*mtxp));
22 if(!mtxp)
23 return NULL;
24
25 // Make room for the mutex
26 mtxp->mtx = malloc(1 * sizeof(*mtxp->mtx));
27 if(!mtxp->mtx) {
28 free(mtxp);
29 return NULL;
30 }
31
32 // Init the mutex
33 if(mtx_init(mtxp->mtx, type) == thrd_error) {
34 free(mtxp); free(mtxp->mtx);
35 RETURNWERR(errno, NULL);
36 }
37
38 mtxp->data = data;
39 return mtxp;
40}
41
42void mtxpair_free(mtxpair *mp) {
43 if(!mp)
44 return;
45
46 mtx_destroy(mp->mtx);
47 free(mp->mtx);
48 free(mp);
49
50 return;
51}
52
53int mtxpair_setdata(mtxpair * const mp, void * const data) {
54 if(!mp)
55 RETURNWERR(EINVAL, -1);
56
57 mp->data = data;
58 return 0;
59}
60
61
62// thrd_create which calls mtx_lock/unlock on `arg` automatically
63int thrd_createwmx(thrd_t * const thr, thrd_start_t func, mtxpair * const mtxd) {
64 if(!thr)
65 RETURNWERR(EINVAL, thrd_error);
66 if(!func)
67 RETURNWERR(EINVAL, thrd_error);
68 if(!mtxd)
69 RETURNWERR(EINVAL, thrd_error);
70
71 if(mtx_lock(mtxd->mtx) == thrd_error) {RETURNWERR(errno, thrd_error);}
72 int retval = thrd_create(thr, func, mtxd->data);
73 if(mtx_unlock(mtxd->mtx) == thrd_error) {RETURNWERR(errno, thrd_error);}
74
75 return retval;
76}
77
78
79/* Ok, after doing a little more research, the best way to do this is probaby via a producer/consumer architecture. Spawn a bunch of
80// threads waiting on a queue (via semaphore) and when one is notified pop a task of the queue and execute it. In this case, the
81// producer would be the filesystem scanner funciton providing new files to encrypt, and the consumers would be threads waiting
82// to encrypt them */
83
84// Threadpool:
85 // Array of threads
86 // Task Queue
87 // Readiness semaphore
88 // Linked List of Tasks
89 // Task:
90 // int (*callback)(void*)
91 // void *arg
92
93// Here's a good reference of this implemented in C++ using Boost: https://gist.github.com/mikeando/482342
94
95typedef struct cq {
96
97} cqueue;
98
99typedef struct task {
100 int (*callback)(void*);
101 void *arg;
102} task;
103typedef struct tp {
104 thrd_t **threads;
105 int nthreads;
106
107 cqueue *taskqueue;
108} threadpool;
109
diff --git a/src/threadpool.h b/src/threadpool.h
new file mode 100644
index 0000000..8e3ee41
--- /dev/null
+++ b/src/threadpool.h
@@ -0,0 +1,13 @@
1#ifndef __VXGG_REWRITE___THREADPOOL_H___13601325413136___
2#define __VXGG_REWRITE___THREADPOOL_H___13601325413136___
3
4#include <threads.h>
5
6typedef struct mtxp mtxpair;
7mtxpair * mtxpair_init(void * const data, int type);
8void mtxpair_free(mtxpair *mp);
9int mtxpair_setdata(mtxpair * const mp, void * const data);
10
11int thrd_createwmx(thrd_t * const thr, thrd_start_t func, mtxpair * const mtxd);
12
13#endif \ No newline at end of file