Jackalope / jlib (public) (License: GPLv3 or later) (since 2019-11-18) (hash sha1)
jlib C++ template library
Used to replace std functionality without exception handling.
- data structures
- filesystem routines
- crossplatform threads interface (currently only pthreads implementation)
- thread pool
- crossplatform dynamic memory functions interface (allocate, reallocate, deallocate) with alignment support
- high percision timer routines based on timespec
List of commits:
Subject Hash Author Date (UTC)
threads refactoring 9b03fd0beb928de9f3f3e492bb1d324356152de3 Jackalope 2020-05-26 08:52:26
changed notice about native compilation 7b48919f0f46df08f14c8a867d7d1c5d14c19efb Jackalope 2020-05-24 16:37:16
remove LTO option a95b60656c6c00d64efd769d5047853315964556 Jackalope 2020-05-24 13:39:59
compiler options and optimizations 92bc2d91c14c58ce630a7f4f400b5d076ac03286 Jackalope 2020-05-24 01:16:59
cpu_number return unsigned int b9c11a1b4474747c313957bef5573d1db6c481ff Jackalope 2020-05-24 00:13:29
ThreadPool moved to jl namespace, same for cpu_number function 2e486f0d57347197a875abe79b4c637e7c925ecc Jackalope 2020-05-23 23:26:00
removed inline keyword from functions in fs.cpp 295f11fb3a3f285c5393687675d8dd2c86e726b8 Jackalope 2020-05-23 23:25:12
make assert constexpr compatible again 378556f2203439749e7c4003031c3e1de1511f6d Jackalope 2020-05-23 23:24:04
renamed Doxygen options cbda01d11706d12d842d088e917dd3e7866689a2 Jackalope 2020-05-23 23:23:30
Updated license notice 0d013874b3eca0e34ad14cbb4dc4aa7628549a4b Jackalope 2020-05-23 22:52:50
Moved some implementation to library obj target 43b7241f3ded0b0b049d15bf337dac6b25b577e6 Jackalope 2020-05-23 22:44:45
CMake documentation target 8ab15abc55ba97919ffa4b07bdf9389b0ff57a24 Jackalope 2020-05-23 21:19:36
CMake install target with version control 9e7aaf56c9c3cae628cc8dc35ded5fec49d414b2 Jackalope 2020-05-23 21:10:32
added read whole TEXT file func also (only binary was before) d70894b97e0760c85fa03bf802d36a840d331bc9 Jackalope 2020-05-20 19:05:49
Changed cmake library interface 0b4c87b296597ae929dc1038e9eefbf155250fa7 Jackalope 2020-05-12 06:57:42
added byte_array and byte_array_ro typedefs 902916f777983eba78d325e9f9c9c01bd2502ca3 Jackalope 2020-05-11 07:47:33
remove _BIT postfix from file opening flags 1cf92db6ccb85c2ac0ed7f86fbdfeac97745bd45 Jackalope 2020-05-11 07:46:51
added license 16a67712bb2ffd15263a6a146a06d4860f435645 Jackalope 2020-05-09 23:31:00
code refactoring 7cfcdc6b9382cea7227d44746c166747fced61a0 Jackalope 2020-05-09 23:05:21
add check for threads count to prevent bloating ce23263c2c053dd1374d54c618b6850215077880 Jackalope 2020-04-21 22:11:24
Commit 9b03fd0beb928de9f3f3e492bb1d324356152de3 - threads refactoring
Author: Jackalope
Author date (UTC): 2020-05-26 08:52
Committer name: Jackalope
Committer date (UTC): 2020-05-26 08:53
Parent(s): 7b48919f0f46df08f14c8a867d7d1c5d14c19efb
Signing key:
Tree: 23ab8267741e2f337d3e895b389b02ab3057c584
File Lines added Lines deleted
include/jlib/threads.h 15 8
include/jlib/threads/def.h 52 46
include/jlib/threads/impl_pthreads.inl 144 135
src/thread_pool.cpp 5 5
File include/jlib/threads.h changed (mode: 100644) (index 5615eab..6b5b199)
... ... namespace jl {
27 27 cpu_number(); cpu_number();
28 28 } }
29 29 namespace jl::threads { namespace jl::threads {
30 template<typename Result>
31 using Thread = P_Thread<Result>;
30 template<typename result_t>
31 using Thread [[deprecated]] = thread_pth<result_t>;
32 using Mutex [[deprecated]] = mutex_pth;
33 using Spinlock [[deprecated]] = spinlock_pth;
34 using Condition [[deprecated]] = condition_pth;
32 35
33 using Mutex = P_Mutex;
34 using Spinlock = P_SpinLock;
35 using Condition = P_Condition;
36 template<lock_type T>
37 using Lock [[deprecated]] = typename
38 std::conditional<T == lock_type::SPINLOCK,Spinlock,Mutex>::type;
36 39
37 template<LockType T>
38 using Lock = typename
39 std::conditional<T == LockType::SpinLock,Spinlock, Mutex>::type;
40 template<typename result_t>
41 using thread = Thread<result_t>;
42 template<lock_type T>
43 using lock = Lock<T>;
44 using mutex = mutex_pth;
45 using spinlock = spinlock_pth;
46 using condition = condition_pth;
40 47 } }
41 48 namespace jth = jl::threads; namespace jth = jl::threads;
File include/jlib/threads/def.h changed (mode: 100644) (index 987bfb9..e057f47)
23 23 #include <type_traits> #include <type_traits>
24 24
25 25 namespace jl::threads { namespace jl::threads {
26 enum class LockType {
27 SpinLock, Mutex
26 enum class lock_type {
27 SPINLOCK, MUTEX
28 28 }; };
29 enum class Create { JOINABLE, DETACHED };
30 template<typename lock_t, LockType type>
31 struct Lock_T;
32 template<typename T>
33 struct Condition_T;
34 template<typename thread_t, typename Result>
35 struct Thread_T;
29 template<typename t, lock_type type>
30 struct lock_t;
31 template<typename t>
32 struct condition_t;
33 template<typename result_t>
34 struct thread_decl;
35 template<typename t, typename result_t>
36 struct thread_t;
36 37 } }
37 template<typename lock_t, jl::threads::LockType type>
38 struct jl::threads::Lock_T {
39 [[nodiscard]]
40 inline auto init();
41 inline void destroy();
42 [[nodiscard]]
43 inline bool try_lock();
44 inline void lock();
45 inline void unlock();
46 lock_t m;
38 template<typename T, jl::threads::lock_type type>
39 struct jl::threads::lock_t {
40 [[nodiscard]] auto
41 init();
42 void
43 destroy();
44 [[nodiscard]] bool
45 try_lock();
46 void
47 lock();
48 void
49 unlock();
50 T m;
47 51 }; };
48 52 template<typename T> template<typename T>
49 struct jl::threads::Condition_T {
50 inline void init();
51 inline void destroy();
52 template<typename lock_t>
53 inline void wait(Lock_T<lock_t, LockType::Mutex> *p_mutex);
54 inline void wake_up_threads();
55 inline void wake_up_thread();
53 struct jl::threads::condition_t {
54 void
55 init();
56 void
57 destroy();
58 template<typename LT> void
59 wait(lock_t<LT, lock_type::MUTEX> *p_mutex);
60 void
61 wake_up_threads();
62 void
63 wake_up_thread();
56 64 T m; T m;
57 65 }; };
58 template<typename thread_t, typename Result>
59 struct jl::threads::Thread_T
60 {
61 static_assert (not std::is_void<Result>::value and
62 (std::is_pointer<Result>::value
63 or sizeof (Result) <= sizeof (void*)));
64
65 template <Create mode, typename Arg, Result Func(Arg*)> [[nodiscard]] inline
66 bool run(Arg *p_argument);
67 template <typename Arg, Result Func(Arg*)> [[nodiscard]] inline
68 bool run_deteached(Arg *p_arg);
69 template <typename Arg, Result Func(Arg*)> [[nodiscard]] inline
70 bool run_joinable (Arg *p_arg);
71 template <typename Arg, Result Func(Arg*)> [[nodiscard]] inline
72 bool run(Create mode, Arg *p_argument);
73
74 inline void join();
75 inline void deteach();
76
77 thread_t m;
66 template<typename result_t>
67 struct jl::threads::thread_decl {
68 static_assert(not std::is_void<result_t>::value
69 and
70 (std::is_pointer<result_t>::value
71 or
72 sizeof (result_t) <= sizeof (void*)));
73 template <typename arg, result_t func(arg*)>
74 [[nodiscard]] bool
75 run_deteached(arg *p_arg);
76 template <typename arg, result_t func(arg*)>
77 [[nodiscard]] bool
78 run_joinable (arg *p_arg);
79 template <typename arg, result_t func(arg*)>
80 result_t
81 join();
82 void
83 deteach();
78 84 }; };
File include/jlib/threads/impl_pthreads.inl changed (mode: 100644) (index 07d1cb6..39f26ae)
22 22 #pragma once #pragma once
23 23 #include "def.h" #include "def.h"
24 24 #include <tuple> #include <tuple>
25 #include "../assert.h"
26 25 extern "C" { extern "C" {
27 26 #include <pthread.h> #include <pthread.h>
28 27 } }
28 #include <cstdio>
29 29 #include <cerrno> #include <cerrno>
30 30
31 31 namespace jl::threads { namespace jl::threads {
32 using P_SpinLock_t = pthread_spinlock_t;
33 using P_SpinLock = Lock_T<P_SpinLock_t, LockType::SpinLock>;
34 using P_Mutex_t = pthread_mutex_t;
35 using P_Mutex = Lock_T<P_Mutex_t, LockType::Mutex>;
36 using P_Condition = Condition_T<pthread_cond_t>;
37 template<typename Result>
38 using P_Thread = Thread_T<pthread_t, Result>;
39 template<typename Arg, typename Result, Result Func(Arg*)>
40 void* pthread_run(void *p_data);
32 using spinlock_pth = lock_t<pthread_spinlock_t, lock_type::SPINLOCK>;
33 using mutex_pth = lock_t<pthread_mutex_t, lock_type::MUTEX>;
34 using condition_pth = condition_t<pthread_cond_t>;
35 template<typename result_t>
36 using thread_pth = thread_t<pthread_t, result_t>;
41 37 } }
42 38 namespace jl::threads::check { namespace jl::threads::check {
43 inline bool pthread_mutex(int i);
39 #ifndef NDEBUG
40 [[nodiscard]]
41 inline bool pthread_mutex (int i);
42 [[nodiscard]]
44 43 inline bool pthread_thread(int i); inline bool pthread_thread(int i);
45 inline void pthread_join(int i);
46 inline bool pthread_cond(int i);
44 inline void pthread_join (int i);
45 [[nodiscard]]
46 inline bool pthread_cond (int i);
47 #else
48 [[nodiscard]]
49 inline bool pthread_mutex (int) { return true; }
50 [[nodiscard]]
51 inline bool pthread_thread(int) { return true; }
52 inline void pthread_join (int) {}
53 [[nodiscard]]
54 inline bool pthread_cond (int) { return true; }
55 #endif
47 56 } }
48 template<> [[nodiscard]] inline auto jl::threads::P_SpinLock::init() {
57 template<> [[nodiscard]] inline auto jl::threads::spinlock_pth::
58 init() {
49 59 return bool(pthread_spin_init(&m, 0) == 0); return bool(pthread_spin_init(&m, 0) == 0);
50 60 } }
51 template<> inline void jl::threads::P_SpinLock::destroy() {
61 template<> inline void jl::threads::spinlock_pth::
62 destroy() {
52 63 pthread_spin_destroy(&m); pthread_spin_destroy(&m);
53 64 } }
54 template<> [[nodiscard]] inline bool jl::threads::P_SpinLock::try_lock() {
65 template<> [[nodiscard]] inline bool jl::threads::spinlock_pth::
66 try_lock() {
55 67 //if not 0 - EBUSY - The spin lock is currently locked by another thread. //if not 0 - EBUSY - The spin lock is currently locked by another thread.
56 68 return pthread_spin_trylock(&m) == 0; return pthread_spin_trylock(&m) == 0;
57 69 } }
58 template<> inline void jl::threads::P_SpinLock::lock() {
70 template<> inline void jl::threads::spinlock_pth::
71 lock() {
59 72 auto r = pthread_spin_lock(&m); auto r = pthread_spin_lock(&m);
60 jassert_soft(r != EDEADLOCK,
61 "EDEADLOCK The spinlock detected a deadlock condition.");
73 if (r == EDEADLOCK)
74 fputs("EDEADLOCK The spinlock detected a deadlock condition.", stderr);
62 75 } }
63 template<> inline void jl::threads::P_SpinLock::unlock() {
76 template<> inline void jl::threads::spinlock_pth::
77 unlock() {
64 78 pthread_spin_unlock(&m); pthread_spin_unlock(&m);
65 79 } }
66 inline bool jl::threads::check::pthread_mutex(int i) {
67 80 #ifndef NDEBUG #ifndef NDEBUG
81 [[nodiscard]]
82 inline bool jl::threads::check::
83 pthread_mutex(int i) {
68 84 switch (i) { switch (i) {
69 85 case EINVAL: case EINVAL:
70 fprintf(stderr,
71 "The value specified by mutex does not refer to an initialized "
72 "mutex object. OR The mutex was created with the protocol "
73 "attribute having the value"
74 " PTHREAD_PRIO_PROTECT and the calling thread's priority "
75 "is higher than the mutex's current priority ceiling."); break;
86 fputs("The value specified by mutex does not refer to an initialized "
87 "mutex object. OR The mutex was created with the protocol "
88 "attribute having the value"
89 " PTHREAD_PRIO_PROTECT and the calling thread's priority "
90 "is higher than the mutex's current priority ceiling.", stderr);
91 break;
76 92 case EAGAIN: case EAGAIN:
77 fprintf(stderr,
78 "The mutex could not be acquired because the maximum number "
79 "of recursive locks for mutex has been exceeded."); break;
93 fputs("The mutex could not be acquired because the maximum number "
94 "of recursive locks for mutex has been exceeded.", stderr);
95 break;
80 96 case EDEADLK: case EDEADLK:
81 fprintf(stderr, "The current thread already owns the mutex."); break;
97 fputs("The current thread already owns the mutex.", stderr);
98 break;
82 99 case EPERM: case EPERM:
83 fprintf(stderr, "The current thread does not own the mutex."); break;
100 fputs("The current thread does not own the mutex.", stderr);
101 break;
84 102 } }
85 #endif
86 103 return i == 0; return i == 0;
87 104 } }
88 inline bool jl::threads::check::pthread_thread(int i)
105 [[nodiscard]]
106 inline bool jl::threads::check::
107 pthread_thread(int i)
89 108 { {
90 #ifndef NDEBUG
91 109 switch (i) { switch (i) {
92 110 case EAGAIN: case EAGAIN:
93 fprintf(stderr,
94 "Insufficient resources to create another thread, or a "
95 "system-imposed limit on the number of threads was encountered. "
96 "The latter case may occur in two ways: "
97 "the RLIMIT_NPROC soft resource limit (set via setrlimit(2)), "
98 "which limits the number of process for a real user ID, "
99 "was reached; or the kernel's system-wide limit on the number "
100 "of threads, /proc/sys/kernel/threads-max, was reached."); break;
101 case EINVAL: fprintf(stderr, "Invalid settings in attr."); break;
111 fputs("Insufficient resources to create another thread, or a "
112 "system-imposed limit on the number of threads was encountered. "
113 "The latter case may occur in two ways: "
114 "the RLIMIT_NPROC soft resource limit (set via setrlimit(2)), "
115 "which limits the number of process for a real user ID, "
116 "was reached; or the kernel's system-wide limit on the number "
117 "of threads, /proc/sys/kernel/threads-max, was reached.", stderr);
118 break;
119 case EINVAL:
120 fputs("Invalid settings in attr.", stderr);
121 break;
102 122 case EPERM: case EPERM:
103 fprintf(stderr,
104 "No permission to set the scheduling policy"
105 " and parameters specified in attr."); break;
123 fputs("No permission to set the scheduling policy"
124 " and parameters specified in attr.", stderr);
125 break;
106 126 } }
107 #endif
108 127 return i == 0; return i == 0;
109 128 } }
110 inline void jl::threads::check::pthread_join(int i) {
111 #ifndef NDEBUG
129 inline void jl::threads::check::
130 pthread_join(int i) {
112 131 switch (i) { switch (i) {
113 132 case EDEADLK: case EDEADLK:
114 fprintf(stderr,
115 "A deadlock was detected (e.g., two threads tried to join with "
116 "each other); or thread specifies the calling thread."); break;
133 fputs("A deadlock was detected (e.g., two threads tried to join with "
134 "each other); or thread specifies the calling thread.", stderr);
135 break;
117 136 case EINVAL: case EINVAL:
118 fprintf(stderr,
119 "thread is not a joinable thread. OR Another thread is already "
120 "waiting to join with this thread. "); break;
137 fputs("thread is not a joinable thread. OR Another thread is already "
138 "waiting to join with this thread.", stderr);
139 break;
121 140 case ESRCH: case ESRCH:
122 fprintf(stderr, "No thread with the ID thread could be found."); break;
141 fputs("No thread with the ID thread could be found.", stderr);
142 break;
123 143 } }
124 #else
125 (void)i;
126 #endif
127 144 } }
128 inline bool jl::threads::check::pthread_cond(int i) {
129 #ifndef NDEBUG
145 [[nodiscard]]
146 inline bool jl::threads::check::
147 pthread_cond(int i) {
130 148 switch(i) { switch(i) {
131 149 case EINVAL: case EINVAL:
132 fprintf(stderr, "The cond argument is invalid. "); break;
150 fputs("The cond argument is invalid. ", stderr);
151 break;
133 152 case ETIMEDOUT: case ETIMEDOUT:
134 fprintf(stderr,
135 "The condition variable was not signalled "
136 "before the timeout specified by abstime."); break;
153 fputs("The condition variable was not signalled "
154 "before the timeout specified by abstime.", stderr);
155 break;
137 156 case EBUSY: case EBUSY:
138 fprintf(stderr, "Some threads are currently waiting on cond."); break;
157 fputs("Some threads are currently waiting on cond.", stderr);
158 break;
139 159 } }
140 #endif
141 160 return i == 0; return i == 0;
142 161 } }
143 template<> inline auto jl::threads::P_Mutex::init() {
162 #endif
163 template<> inline auto jl::threads::mutex_pth::
164 init() {
144 165 m = PTHREAD_MUTEX_INITIALIZER; m = PTHREAD_MUTEX_INITIALIZER;
145 166 return; return;
146 167 } }
147 template<> inline void jl::threads::P_Mutex::destroy() {
168 template<> inline void jl::threads::mutex_pth::
169 destroy() {
148 170 pthread_mutex_destroy(&m); pthread_mutex_destroy(&m);
149 171 } }
150 template<> [[nodiscard]] inline bool jl::threads::P_Mutex::try_lock() {
172 template<> [[nodiscard]] inline bool jl::threads::mutex_pth::
173 try_lock() {
151 174 return check::pthread_mutex(pthread_mutex_trylock(&m)); return check::pthread_mutex(pthread_mutex_trylock(&m));
152 // if false - EBUSY - The spin lock is currently locked by another thread.
153 175 } }
154 template<> inline void jl::threads::P_Mutex::lock() {
155 check::pthread_mutex(pthread_mutex_lock(&m));
176 template<> inline void jl::threads::mutex_pth::
177 lock() {
178 (void)check::pthread_mutex(pthread_mutex_lock(&m));
156 179 } }
157 template<> inline void jl::threads::P_Mutex::unlock() {
158 check::pthread_mutex(pthread_mutex_unlock(&m));
180 template<> inline void jl::threads::mutex_pth::
181 unlock() {
182 (void)check::pthread_mutex(pthread_mutex_unlock(&m));
159 183 } }
160 template<> inline void jl::threads::P_Condition::init() {
184 template<> inline void jl::threads::condition_pth::init() {
161 185 m = PTHREAD_COND_INITIALIZER; m = PTHREAD_COND_INITIALIZER;
162 186 } }
163 template<> inline void jl::threads::P_Condition::destroy() {
164 check::pthread_cond(pthread_cond_destroy(&m));
165 }
166 template<>template<>inline void jl::threads::P_Condition::wait(P_Mutex *p_m) {
167 check::pthread_cond(pthread_cond_wait(&m, &p_m->m));
168 }
169 template<> inline void jl::threads::P_Condition::wake_up_threads() {
170 check::pthread_cond(pthread_cond_broadcast(&m));
171 }
172 template<> inline void jl::threads::P_Condition::wake_up_thread() {
173 check::pthread_cond(pthread_cond_signal(&m));
174 }
175 template<typename Arg, typename Result, Result Func(Arg*)>
176 void* jl::threads::pthread_run(void *p_data) {
177 Arg *p_arg = static_cast<Arg*>(p_data);
178 return reinterpret_cast<void*>(Func(p_arg));
179 }
180 template<typename Result> struct jl::threads::Thread_T<pthread_t, Result> {
181 static_assert (not std::is_void<Result>::value and
182 (std::is_pointer<Result>::value
183 or sizeof (Result) <= sizeof (void*)));
184 template <Create mode, typename Arg, Result Func(Arg*)>
185 [[nodiscard]] inline bool run(Arg *p_arg) {
186 switch (mode) {
187 case Create::JOINABLE: {
188 auto r = pthread_create(&m, {}, pthread_run<Arg, Result, Func>, p_arg);
189 return check::pthread_thread(r);
190 }
191 case Create::DETACHED: {
192 pthread_attr_t a;
193 bool r = pthread_attr_init(&a) == 0;
194 if (not r)
195 return false;
196 pthread_attr_setdetachstate(&a, PTHREAD_CREATE_DETACHED);
197 int p = pthread_create(&m, &a, pthread_run<Arg, Result, Func>, p_arg);
198 r = check::pthread_thread(p);
199 pthread_attr_destroy(&a);
200 return r;
201 }
202 }
203 }
204 template <typename Arg, Result Func(Arg*)>
205 [[nodiscard]] inline bool run_deteached(Arg *p_arg) {
206 return run<Create::DETACHED, Arg, Func>(p_arg);
207 }
208 template <typename Arg, Result Func(Arg*)>
209 [[nodiscard]] inline bool run_joinable(Arg *p_arg) {
210 return run<Create::JOINABLE, Arg, Func>(p_arg);
187 template<> inline void jl::threads::condition_pth::
188 destroy() {
189 (void)check::pthread_cond(pthread_cond_destroy(&m));
190 }
191 template<> template<> inline void jl::threads::condition_pth::
192 wait(mutex_pth *p_m) {
193 (void)check::pthread_cond(pthread_cond_wait(&m, &p_m->m));
194 }
195 template<> inline void jl::threads::condition_pth::
196 wake_up_threads() {
197 (void)check::pthread_cond(pthread_cond_broadcast(&m));
198 }
199 template<> inline void jl::threads::condition_pth::
200 wake_up_thread() {
201 (void)check::pthread_cond(pthread_cond_signal(&m));
202 }
203 template<typename result_t>
204 struct jl::threads::thread_t<pthread_t, result_t> : thread_decl<result_t>
205 {
206 template <typename arg>
207 [[nodiscard]] bool
208 run_deteached(arg *p_arg, result_t func(arg*)) {
209 pthread_attr_t a;
210 if (pthread_attr_init(&a) != 0)
211 return false;
212 pthread_attr_setdetachstate(&a, PTHREAD_CREATE_DETACHED);
213 auto p_func = reinterpret_cast<void*(*)(void*)>(func);
214 int p = pthread_create(&m, &a, p_func, p_arg);
215 bool r = check::pthread_thread(p);
216 pthread_attr_destroy(&a);
217 return r;
211 218 } }
212 template <typename Arg, Result Func(Arg*)>
213 [[nodiscard]] inline bool run(Create mode, Arg *p_argument) {
214 if (mode == Create::DETACHED)
215 return run<Create::DETACHED, Arg, Func>(p_argument);
216 else
217 return run<Create::JOINABLE, Arg, Func>(p_argument);
219 template <typename arg>
220 [[nodiscard]] bool
221 run_joinable(arg *p_arg, result_t func(arg*)) {
222 auto p_func = reinterpret_cast<void*(*)(void*)>(func);
223 auto r = pthread_create(&m, {}, p_func, p_arg);
224 return check::pthread_thread(r);
218 225 } }
219 inline Result join() {
220 void * res;
226 result_t
227 join() {
228 void *res;
221 229 check::pthread_join(pthread_join(m, &res)); check::pthread_join(pthread_join(m, &res));
222 return static_cast<Result>(reinterpret_cast<intptr_t>(res));
230 return static_cast<result_t>(reinterpret_cast<intptr_t>(res));
223 231 } }
224 inline void deteach() {
232 void
233 deteach() {
225 234 check::pthread_join(pthread_detach(m)); check::pthread_join(pthread_detach(m));
226 235 } }
227 236 pthread_t m; pthread_t m;
File src/thread_pool.cpp changed (mode: 100644) (index 06458d9..141bcca)
... ... using namespace jl;
26 26 using namespace jl::threads; using namespace jl::threads;
27 27 struct TaskQueues { struct TaskQueues {
28 28 jl::rarray<jl::darray<Task>> queues; jl::rarray<jl::darray<Task>> queues;
29 Mutex queues_lock;
29 mutex queues_lock;
30 30 unsigned int in_progress_count; unsigned int in_progress_count;
31 Condition idle_condition;
32 Condition condition;
31 condition idle_condition;
32 condition condition;
33 33 bool has_tasks; bool has_tasks;
34 34 bool brodcast_empty; bool brodcast_empty;
35 35 }; };
 
... ... struct TaskQueueSequential {
50 50 void void
51 51 destroy() { tasks.destroy(); } destroy() { tasks.destroy(); }
52 52 jl::darray<TaskSequential> tasks; jl::darray<TaskSequential> tasks;
53 Mutex tasks_lock;
53 mutex tasks_lock;
54 54 bool is_failed; bool is_failed;
55 55 }; };
56 56 struct ThreadData { struct ThreadData {
 
... ... pool_run(ThreadPool::Data *p, unsigned int thread_count,
253 253 auto &fd = p->threads[i]; auto &fd = p->threads[i];
254 254 fd.is_dead = false; fd.is_dead = false;
255 255 fd.p_data = p; fd.p_data = p;
256 if (not fd.instance.run<Create::JOINABLE, ThreadData, thread_loop>(&fd)) {
256 if (not fd.instance.run_joinable(&fd, &thread_loop)) {
257 257 p->stop_work = true; p->stop_work = true;
258 258 while(i > 0) while(i > 0)
259 259 p->threads[--i].instance.join(); p->threads[--i].instance.join();
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/Jackalope/jlib

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/Jackalope/jlib

Clone this repository using git:
git clone git://git.rocketgit.com/user/Jackalope/jlib

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main