extlzham 0.0.1.PROTOTYPE3-x86-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE.md +27 -0
- data/README.md +74 -0
- data/Rakefile +152 -0
- data/contrib/lzham/LICENSE +22 -0
- data/contrib/lzham/README.md +209 -0
- data/contrib/lzham/include/lzham.h +781 -0
- data/contrib/lzham/lzhamcomp/lzham_comp.h +38 -0
- data/contrib/lzham/lzhamcomp/lzham_lzbase.cpp +244 -0
- data/contrib/lzham/lzhamcomp/lzham_lzbase.h +45 -0
- data/contrib/lzham/lzhamcomp/lzham_lzcomp.cpp +608 -0
- data/contrib/lzham/lzhamcomp/lzham_lzcomp_internal.cpp +1966 -0
- data/contrib/lzham/lzhamcomp/lzham_lzcomp_internal.h +472 -0
- data/contrib/lzham/lzhamcomp/lzham_lzcomp_state.cpp +1413 -0
- data/contrib/lzham/lzhamcomp/lzham_match_accel.cpp +562 -0
- data/contrib/lzham/lzhamcomp/lzham_match_accel.h +146 -0
- data/contrib/lzham/lzhamcomp/lzham_null_threading.h +97 -0
- data/contrib/lzham/lzhamcomp/lzham_pthreads_threading.cpp +229 -0
- data/contrib/lzham/lzhamcomp/lzham_pthreads_threading.h +520 -0
- data/contrib/lzham/lzhamcomp/lzham_threading.h +12 -0
- data/contrib/lzham/lzhamcomp/lzham_win32_threading.cpp +220 -0
- data/contrib/lzham/lzhamcomp/lzham_win32_threading.h +368 -0
- data/contrib/lzham/lzhamdecomp/lzham_assert.cpp +66 -0
- data/contrib/lzham/lzhamdecomp/lzham_assert.h +40 -0
- data/contrib/lzham/lzhamdecomp/lzham_checksum.cpp +73 -0
- data/contrib/lzham/lzhamdecomp/lzham_checksum.h +13 -0
- data/contrib/lzham/lzhamdecomp/lzham_config.h +23 -0
- data/contrib/lzham/lzhamdecomp/lzham_core.h +264 -0
- data/contrib/lzham/lzhamdecomp/lzham_decomp.h +37 -0
- data/contrib/lzham/lzhamdecomp/lzham_helpers.h +54 -0
- data/contrib/lzham/lzhamdecomp/lzham_huffman_codes.cpp +262 -0
- data/contrib/lzham/lzhamdecomp/lzham_huffman_codes.h +14 -0
- data/contrib/lzham/lzhamdecomp/lzham_lzdecomp.cpp +1527 -0
- data/contrib/lzham/lzhamdecomp/lzham_lzdecompbase.cpp +131 -0
- data/contrib/lzham/lzhamdecomp/lzham_lzdecompbase.h +89 -0
- data/contrib/lzham/lzhamdecomp/lzham_math.h +142 -0
- data/contrib/lzham/lzhamdecomp/lzham_mem.cpp +284 -0
- data/contrib/lzham/lzhamdecomp/lzham_mem.h +112 -0
- data/contrib/lzham/lzhamdecomp/lzham_platform.cpp +157 -0
- data/contrib/lzham/lzhamdecomp/lzham_platform.h +284 -0
- data/contrib/lzham/lzhamdecomp/lzham_prefix_coding.cpp +351 -0
- data/contrib/lzham/lzhamdecomp/lzham_prefix_coding.h +146 -0
- data/contrib/lzham/lzhamdecomp/lzham_symbol_codec.cpp +1484 -0
- data/contrib/lzham/lzhamdecomp/lzham_symbol_codec.h +556 -0
- data/contrib/lzham/lzhamdecomp/lzham_timer.cpp +147 -0
- data/contrib/lzham/lzhamdecomp/lzham_timer.h +99 -0
- data/contrib/lzham/lzhamdecomp/lzham_traits.h +141 -0
- data/contrib/lzham/lzhamdecomp/lzham_types.h +97 -0
- data/contrib/lzham/lzhamdecomp/lzham_utils.h +58 -0
- data/contrib/lzham/lzhamdecomp/lzham_vector.cpp +75 -0
- data/contrib/lzham/lzhamdecomp/lzham_vector.h +588 -0
- data/contrib/lzham/lzhamlib/lzham_lib.cpp +179 -0
- data/examples/basic.rb +48 -0
- data/ext/constants.c +64 -0
- data/ext/decoder.c +313 -0
- data/ext/depend +5 -0
- data/ext/encoder.c +372 -0
- data/ext/error.c +80 -0
- data/ext/extconf.rb +29 -0
- data/ext/extlzham.c +34 -0
- data/ext/extlzham.h +62 -0
- data/gemstub.rb +22 -0
- data/lib/2.0/extlzham.so +0 -0
- data/lib/2.1/extlzham.so +0 -0
- data/lib/2.2/extlzham.so +0 -0
- data/lib/extlzham.rb +158 -0
- data/lib/extlzham/version.rb +5 -0
- data/test/test_extlzham.rb +35 -0
- metadata +156 -0
@@ -0,0 +1,520 @@
|
|
1
|
+
// File: lzham_task_pool_pthreads.h
|
2
|
+
// See Copyright Notice and license at the end of include/lzham.h
|
3
|
+
#pragma once
|
4
|
+
|
5
|
+
#if LZHAM_USE_PTHREADS_API
|
6
|
+
|
7
|
+
#if LZHAM_NO_ATOMICS
|
8
|
+
#error No atomic operations defined in lzham_platform.h!
|
9
|
+
#endif
|
10
|
+
|
11
|
+
#ifdef __APPLE__
|
12
|
+
#include <libkern/OSAtomic.h>
|
13
|
+
#endif
|
14
|
+
|
15
|
+
#include <pthread.h>
|
16
|
+
#include <semaphore.h>
|
17
|
+
#include <unistd.h>
|
18
|
+
#include <sys/time.h>
|
19
|
+
|
20
|
+
#define LZHAM_RND_CONG(jcong) (69069U * jcong + 1234567U)
|
21
|
+
|
22
|
+
namespace lzham
|
23
|
+
{
|
24
|
+
// semaphore
|
25
|
+
|
26
|
+
#ifdef __APPLE__
|
27
|
+
class semaphore
|
28
|
+
{
|
29
|
+
LZHAM_NO_COPY_OR_ASSIGNMENT_OP(semaphore);
|
30
|
+
|
31
|
+
public:
|
32
|
+
inline semaphore(long initialCount, long maximumCount)
|
33
|
+
{
|
34
|
+
LZHAM_NOTE_UNUSED(maximumCount);
|
35
|
+
LZHAM_ASSERT(maximumCount >= initialCount);
|
36
|
+
|
37
|
+
for (uint tries = 0; tries < 16; tries++)
|
38
|
+
{
|
39
|
+
struct timeval tp;
|
40
|
+
struct timezone tzp;
|
41
|
+
gettimeofday(&tp, &tzp);
|
42
|
+
uint x = tp.tv_usec;
|
43
|
+
|
44
|
+
// Argh this stinks. Try to choose a name that won't conflict with anything the calling process uses.
|
45
|
+
for (uint i = 0; i < sizeof(m_name) - 1; i++)
|
46
|
+
{
|
47
|
+
x = LZHAM_RND_CONG(x);
|
48
|
+
char c = 'A' + (static_cast<uint8>(x ^ (x >> 20)) % 26);
|
49
|
+
m_name[i] = c;
|
50
|
+
}
|
51
|
+
m_name[sizeof(m_name) - 1] = '\0';
|
52
|
+
|
53
|
+
m_pSem = sem_open(m_name, O_CREAT | O_EXCL, S_IRWXU, initialCount);
|
54
|
+
if (m_pSem != SEM_FAILED)
|
55
|
+
break;
|
56
|
+
}
|
57
|
+
|
58
|
+
if (m_pSem == SEM_FAILED)
|
59
|
+
{
|
60
|
+
LZHAM_FAIL("semaphore: sem_init() failed");
|
61
|
+
}
|
62
|
+
}
|
63
|
+
|
64
|
+
inline ~semaphore()
|
65
|
+
{
|
66
|
+
sem_close(m_pSem);
|
67
|
+
sem_unlink(m_name);
|
68
|
+
}
|
69
|
+
|
70
|
+
inline void release(long releaseCount = 1)
|
71
|
+
{
|
72
|
+
LZHAM_ASSERT(releaseCount >= 1);
|
73
|
+
|
74
|
+
int status = 0;
|
75
|
+
#ifdef WIN32
|
76
|
+
if (1 == releaseCount)
|
77
|
+
status = sem_post(m_pSem);
|
78
|
+
else
|
79
|
+
status = sem_post_multiple(m_pSem, releaseCount);
|
80
|
+
#else
|
81
|
+
while (releaseCount > 0)
|
82
|
+
{
|
83
|
+
status = sem_post(m_pSem);
|
84
|
+
if (status)
|
85
|
+
break;
|
86
|
+
releaseCount--;
|
87
|
+
}
|
88
|
+
#endif
|
89
|
+
|
90
|
+
if (status)
|
91
|
+
{
|
92
|
+
LZHAM_FAIL("semaphore: sem_post() or sem_post_multiple() failed");
|
93
|
+
}
|
94
|
+
}
|
95
|
+
|
96
|
+
inline bool wait()
|
97
|
+
{
|
98
|
+
int status = sem_wait(m_pSem);
|
99
|
+
|
100
|
+
if (status)
|
101
|
+
{
|
102
|
+
if (errno != ETIMEDOUT)
|
103
|
+
{
|
104
|
+
LZHAM_FAIL("semaphore: sem_wait() or sem_timedwait() failed");
|
105
|
+
}
|
106
|
+
return false;
|
107
|
+
}
|
108
|
+
|
109
|
+
return true;
|
110
|
+
}
|
111
|
+
|
112
|
+
private:
|
113
|
+
sem_t *m_pSem;
|
114
|
+
char m_name[16];
|
115
|
+
};
|
116
|
+
#else
|
117
|
+
class semaphore
|
118
|
+
{
|
119
|
+
LZHAM_NO_COPY_OR_ASSIGNMENT_OP(semaphore);
|
120
|
+
|
121
|
+
public:
|
122
|
+
inline semaphore(long initialCount = 0, long maximumCount = 1, const char* pName = NULL)
|
123
|
+
{
|
124
|
+
LZHAM_NOTE_UNUSED(maximumCount), LZHAM_NOTE_UNUSED(pName);
|
125
|
+
LZHAM_ASSERT(maximumCount >= initialCount);
|
126
|
+
if (sem_init(&m_sem, 0, initialCount))
|
127
|
+
{
|
128
|
+
LZHAM_FAIL("semaphore: sem_init() failed");
|
129
|
+
}
|
130
|
+
}
|
131
|
+
|
132
|
+
inline ~semaphore()
|
133
|
+
{
|
134
|
+
sem_destroy(&m_sem);
|
135
|
+
}
|
136
|
+
|
137
|
+
inline void release(long releaseCount = 1)
|
138
|
+
{
|
139
|
+
LZHAM_ASSERT(releaseCount >= 1);
|
140
|
+
|
141
|
+
int status = 0;
|
142
|
+
#ifdef WIN32
|
143
|
+
if (1 == releaseCount)
|
144
|
+
status = sem_post(&m_sem);
|
145
|
+
else
|
146
|
+
status = sem_post_multiple(&m_sem, releaseCount);
|
147
|
+
#else
|
148
|
+
while (releaseCount > 0)
|
149
|
+
{
|
150
|
+
status = sem_post(&m_sem);
|
151
|
+
if (status)
|
152
|
+
break;
|
153
|
+
releaseCount--;
|
154
|
+
}
|
155
|
+
#endif
|
156
|
+
|
157
|
+
if (status)
|
158
|
+
{
|
159
|
+
LZHAM_FAIL("semaphore: sem_post() or sem_post_multiple() failed");
|
160
|
+
}
|
161
|
+
}
|
162
|
+
|
163
|
+
inline bool wait(uint32 milliseconds = UINT32_MAX)
|
164
|
+
{
|
165
|
+
int status;
|
166
|
+
if (milliseconds == UINT32_MAX)
|
167
|
+
{
|
168
|
+
status = sem_wait(&m_sem);
|
169
|
+
}
|
170
|
+
else
|
171
|
+
{
|
172
|
+
struct timespec interval;
|
173
|
+
interval.tv_sec = milliseconds / 1000;
|
174
|
+
interval.tv_nsec = (milliseconds % 1000) * 1000000L;
|
175
|
+
status = sem_timedwait(&m_sem, &interval);
|
176
|
+
}
|
177
|
+
|
178
|
+
if (status)
|
179
|
+
{
|
180
|
+
if (errno != ETIMEDOUT)
|
181
|
+
{
|
182
|
+
LZHAM_FAIL("semaphore: sem_wait() or sem_timedwait() failed");
|
183
|
+
}
|
184
|
+
return false;
|
185
|
+
}
|
186
|
+
|
187
|
+
return true;
|
188
|
+
}
|
189
|
+
|
190
|
+
private:
|
191
|
+
sem_t m_sem;
|
192
|
+
};
|
193
|
+
#endif
|
194
|
+
|
195
|
+
// spinlock
|
196
|
+
|
197
|
+
#ifdef __APPLE__
|
198
|
+
class spinlock
|
199
|
+
{
|
200
|
+
public:
|
201
|
+
inline spinlock() : m_lock(0)
|
202
|
+
{
|
203
|
+
}
|
204
|
+
|
205
|
+
inline ~spinlock()
|
206
|
+
{
|
207
|
+
}
|
208
|
+
|
209
|
+
inline void lock()
|
210
|
+
{
|
211
|
+
OSSpinLockLock(&m_lock);
|
212
|
+
}
|
213
|
+
|
214
|
+
inline void unlock()
|
215
|
+
{
|
216
|
+
OSSpinLockUnlock(&m_lock);
|
217
|
+
}
|
218
|
+
|
219
|
+
private:
|
220
|
+
|
221
|
+
OSSpinLock m_lock;
|
222
|
+
};
|
223
|
+
#else
|
224
|
+
class spinlock
|
225
|
+
{
|
226
|
+
public:
|
227
|
+
inline spinlock()
|
228
|
+
{
|
229
|
+
if (pthread_spin_init(&m_spinlock, 0))
|
230
|
+
{
|
231
|
+
LZHAM_FAIL("spinlock: pthread_spin_init() failed");
|
232
|
+
}
|
233
|
+
}
|
234
|
+
|
235
|
+
inline ~spinlock()
|
236
|
+
{
|
237
|
+
pthread_spin_destroy(&m_spinlock);
|
238
|
+
}
|
239
|
+
|
240
|
+
inline void lock()
|
241
|
+
{
|
242
|
+
if (pthread_spin_lock(&m_spinlock))
|
243
|
+
{
|
244
|
+
LZHAM_FAIL("spinlock: pthread_spin_lock() failed");
|
245
|
+
}
|
246
|
+
}
|
247
|
+
|
248
|
+
inline void unlock()
|
249
|
+
{
|
250
|
+
if (pthread_spin_unlock(&m_spinlock))
|
251
|
+
{
|
252
|
+
LZHAM_FAIL("spinlock: pthread_spin_unlock() failed");
|
253
|
+
}
|
254
|
+
}
|
255
|
+
|
256
|
+
private:
|
257
|
+
pthread_spinlock_t m_spinlock;
|
258
|
+
};
|
259
|
+
#endif // __APPLE__
|
260
|
+
|
261
|
+
// Thread safe stack
|
262
|
+
|
263
|
+
template<typename T, uint cMaxSize>
|
264
|
+
class tsstack
|
265
|
+
{
|
266
|
+
public:
|
267
|
+
inline tsstack() : m_top(0)
|
268
|
+
{
|
269
|
+
}
|
270
|
+
|
271
|
+
inline ~tsstack()
|
272
|
+
{
|
273
|
+
}
|
274
|
+
|
275
|
+
inline void clear()
|
276
|
+
{
|
277
|
+
m_spinlock.lock();
|
278
|
+
m_top = 0;
|
279
|
+
m_spinlock.unlock();
|
280
|
+
}
|
281
|
+
|
282
|
+
inline bool try_push(const T& obj)
|
283
|
+
{
|
284
|
+
bool result = false;
|
285
|
+
m_spinlock.lock();
|
286
|
+
if (m_top < (int)cMaxSize)
|
287
|
+
{
|
288
|
+
m_stack[m_top++] = obj;
|
289
|
+
result = true;
|
290
|
+
}
|
291
|
+
m_spinlock.unlock();
|
292
|
+
return result;
|
293
|
+
}
|
294
|
+
|
295
|
+
inline bool pop(T& obj)
|
296
|
+
{
|
297
|
+
bool result = false;
|
298
|
+
m_spinlock.lock();
|
299
|
+
if (m_top > 0)
|
300
|
+
{
|
301
|
+
obj = m_stack[--m_top];
|
302
|
+
result = true;
|
303
|
+
}
|
304
|
+
m_spinlock.unlock();
|
305
|
+
return result;
|
306
|
+
}
|
307
|
+
|
308
|
+
private:
|
309
|
+
spinlock m_spinlock;
|
310
|
+
T m_stack[cMaxSize];
|
311
|
+
int m_top;
|
312
|
+
};
|
313
|
+
|
314
|
+
// Simple task pool
|
315
|
+
|
316
|
+
class task_pool
|
317
|
+
{
|
318
|
+
public:
|
319
|
+
task_pool();
|
320
|
+
task_pool(uint num_threads);
|
321
|
+
~task_pool();
|
322
|
+
|
323
|
+
enum { cMaxThreads = LZHAM_MAX_HELPER_THREADS };
|
324
|
+
bool init(uint num_threads);
|
325
|
+
void deinit();
|
326
|
+
|
327
|
+
inline uint get_num_threads() const { return m_num_threads; }
|
328
|
+
inline uint get_num_outstanding_tasks() const { return static_cast<uint>(m_num_outstanding_tasks); }
|
329
|
+
|
330
|
+
// C-style task callback
|
331
|
+
typedef void (*task_callback_func)(uint64 data, void* pData_ptr);
|
332
|
+
bool queue_task(task_callback_func pFunc, uint64 data = 0, void* pData_ptr = NULL);
|
333
|
+
|
334
|
+
class executable_task
|
335
|
+
{
|
336
|
+
public:
|
337
|
+
virtual void execute_task(uint64 data, void* pData_ptr) = 0;
|
338
|
+
};
|
339
|
+
|
340
|
+
// It's the caller's responsibility to delete pObj within the execute_task() method, if needed!
|
341
|
+
bool queue_task(executable_task* pObj, uint64 data = 0, void* pData_ptr = NULL);
|
342
|
+
|
343
|
+
template<typename S, typename T>
|
344
|
+
inline bool queue_object_task(S* pObject, T pObject_method, uint64 data = 0, void* pData_ptr = NULL);
|
345
|
+
|
346
|
+
template<typename S, typename T>
|
347
|
+
inline bool queue_multiple_object_tasks(S* pObject, T pObject_method, uint64 first_data, uint num_tasks, void* pData_ptr = NULL);
|
348
|
+
|
349
|
+
void join();
|
350
|
+
|
351
|
+
private:
|
352
|
+
struct task
|
353
|
+
{
|
354
|
+
inline task() : m_data(0), m_pData_ptr(NULL), m_pObj(NULL), m_flags(0) { }
|
355
|
+
|
356
|
+
uint64 m_data;
|
357
|
+
void* m_pData_ptr;
|
358
|
+
|
359
|
+
union
|
360
|
+
{
|
361
|
+
task_callback_func m_callback;
|
362
|
+
executable_task* m_pObj;
|
363
|
+
};
|
364
|
+
|
365
|
+
uint m_flags;
|
366
|
+
};
|
367
|
+
|
368
|
+
tsstack<task, cMaxThreads> m_task_stack;
|
369
|
+
|
370
|
+
uint m_num_threads;
|
371
|
+
pthread_t m_threads[cMaxThreads];
|
372
|
+
|
373
|
+
semaphore m_tasks_available;
|
374
|
+
|
375
|
+
enum task_flags
|
376
|
+
{
|
377
|
+
cTaskFlagObject = 1
|
378
|
+
};
|
379
|
+
|
380
|
+
volatile atomic32_t m_num_outstanding_tasks;
|
381
|
+
volatile atomic32_t m_exit_flag;
|
382
|
+
|
383
|
+
void process_task(task& tsk);
|
384
|
+
|
385
|
+
static void* thread_func(void *pContext);
|
386
|
+
};
|
387
|
+
|
388
|
+
enum object_task_flags
|
389
|
+
{
|
390
|
+
cObjectTaskFlagDefault = 0,
|
391
|
+
cObjectTaskFlagDeleteAfterExecution = 1
|
392
|
+
};
|
393
|
+
|
394
|
+
template<typename T>
|
395
|
+
class object_task : public task_pool::executable_task
|
396
|
+
{
|
397
|
+
public:
|
398
|
+
object_task(uint flags = cObjectTaskFlagDefault) :
|
399
|
+
m_pObject(NULL),
|
400
|
+
m_pMethod(NULL),
|
401
|
+
m_flags(flags)
|
402
|
+
{
|
403
|
+
}
|
404
|
+
|
405
|
+
typedef void (T::*object_method_ptr)(uint64 data, void* pData_ptr);
|
406
|
+
|
407
|
+
object_task(T* pObject, object_method_ptr pMethod, uint flags = cObjectTaskFlagDefault) :
|
408
|
+
m_pObject(pObject),
|
409
|
+
m_pMethod(pMethod),
|
410
|
+
m_flags(flags)
|
411
|
+
{
|
412
|
+
LZHAM_ASSERT(pObject && pMethod);
|
413
|
+
}
|
414
|
+
|
415
|
+
void init(T* pObject, object_method_ptr pMethod, uint flags = cObjectTaskFlagDefault)
|
416
|
+
{
|
417
|
+
LZHAM_ASSERT(pObject && pMethod);
|
418
|
+
|
419
|
+
m_pObject = pObject;
|
420
|
+
m_pMethod = pMethod;
|
421
|
+
m_flags = flags;
|
422
|
+
}
|
423
|
+
|
424
|
+
T* get_object() const { return m_pObject; }
|
425
|
+
object_method_ptr get_method() const { return m_pMethod; }
|
426
|
+
|
427
|
+
virtual void execute_task(uint64 data, void* pData_ptr)
|
428
|
+
{
|
429
|
+
(m_pObject->*m_pMethod)(data, pData_ptr);
|
430
|
+
|
431
|
+
if (m_flags & cObjectTaskFlagDeleteAfterExecution)
|
432
|
+
lzham_delete(this);
|
433
|
+
}
|
434
|
+
|
435
|
+
protected:
|
436
|
+
T* m_pObject;
|
437
|
+
|
438
|
+
object_method_ptr m_pMethod;
|
439
|
+
|
440
|
+
uint m_flags;
|
441
|
+
};
|
442
|
+
|
443
|
+
template<typename S, typename T>
|
444
|
+
inline bool task_pool::queue_object_task(S* pObject, T pObject_method, uint64 data, void* pData_ptr)
|
445
|
+
{
|
446
|
+
object_task<S> *pTask = lzham_new< object_task<S> >(pObject, pObject_method, cObjectTaskFlagDeleteAfterExecution);
|
447
|
+
if (!pTask)
|
448
|
+
return false;
|
449
|
+
return queue_task(pTask, data, pData_ptr);
|
450
|
+
}
|
451
|
+
|
452
|
+
template<typename S, typename T>
|
453
|
+
inline bool task_pool::queue_multiple_object_tasks(S* pObject, T pObject_method, uint64 first_data, uint num_tasks, void* pData_ptr)
|
454
|
+
{
|
455
|
+
LZHAM_ASSERT(m_num_threads);
|
456
|
+
LZHAM_ASSERT(pObject);
|
457
|
+
LZHAM_ASSERT(num_tasks);
|
458
|
+
if (!num_tasks)
|
459
|
+
return true;
|
460
|
+
|
461
|
+
bool status = true;
|
462
|
+
|
463
|
+
uint i;
|
464
|
+
for (i = 0; i < num_tasks; i++)
|
465
|
+
{
|
466
|
+
task tsk;
|
467
|
+
|
468
|
+
tsk.m_pObj = lzham_new< object_task<S> >(pObject, pObject_method, cObjectTaskFlagDeleteAfterExecution);
|
469
|
+
if (!tsk.m_pObj)
|
470
|
+
{
|
471
|
+
status = false;
|
472
|
+
break;
|
473
|
+
}
|
474
|
+
|
475
|
+
tsk.m_data = first_data + i;
|
476
|
+
tsk.m_pData_ptr = pData_ptr;
|
477
|
+
tsk.m_flags = cTaskFlagObject;
|
478
|
+
|
479
|
+
if (!m_task_stack.try_push(tsk))
|
480
|
+
{
|
481
|
+
status = false;
|
482
|
+
break;
|
483
|
+
}
|
484
|
+
}
|
485
|
+
|
486
|
+
if (i)
|
487
|
+
{
|
488
|
+
atomic_add32(&m_num_outstanding_tasks, i);
|
489
|
+
|
490
|
+
m_tasks_available.release(i);
|
491
|
+
}
|
492
|
+
|
493
|
+
return status;
|
494
|
+
}
|
495
|
+
|
496
|
+
// Sleep
|
497
|
+
|
498
|
+
inline void lzham_sleep(unsigned int milliseconds)
|
499
|
+
{
|
500
|
+
#ifdef WIN32
|
501
|
+
struct timespec interval;
|
502
|
+
interval.tv_sec = milliseconds / 1000;
|
503
|
+
interval.tv_nsec = (milliseconds % 1000) * 1000000L;
|
504
|
+
pthread_delay_np(&interval);
|
505
|
+
#else
|
506
|
+
while (milliseconds)
|
507
|
+
{
|
508
|
+
int msecs_to_sleep = LZHAM_MIN(milliseconds, 1000);
|
509
|
+
usleep(msecs_to_sleep * 1000);
|
510
|
+
milliseconds -= msecs_to_sleep;
|
511
|
+
}
|
512
|
+
#endif
|
513
|
+
}
|
514
|
+
|
515
|
+
// Returns number of helper threads we can add to the process on the current system (i.e. for a 4 CPU system this returns 3).
|
516
|
+
uint lzham_get_max_helper_threads();
|
517
|
+
|
518
|
+
} // namespace lzham
|
519
|
+
|
520
|
+
#endif // LZHAM_USE_PTHREADS_API
|