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.
Files changed (69) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.md +27 -0
  3. data/README.md +74 -0
  4. data/Rakefile +152 -0
  5. data/contrib/lzham/LICENSE +22 -0
  6. data/contrib/lzham/README.md +209 -0
  7. data/contrib/lzham/include/lzham.h +781 -0
  8. data/contrib/lzham/lzhamcomp/lzham_comp.h +38 -0
  9. data/contrib/lzham/lzhamcomp/lzham_lzbase.cpp +244 -0
  10. data/contrib/lzham/lzhamcomp/lzham_lzbase.h +45 -0
  11. data/contrib/lzham/lzhamcomp/lzham_lzcomp.cpp +608 -0
  12. data/contrib/lzham/lzhamcomp/lzham_lzcomp_internal.cpp +1966 -0
  13. data/contrib/lzham/lzhamcomp/lzham_lzcomp_internal.h +472 -0
  14. data/contrib/lzham/lzhamcomp/lzham_lzcomp_state.cpp +1413 -0
  15. data/contrib/lzham/lzhamcomp/lzham_match_accel.cpp +562 -0
  16. data/contrib/lzham/lzhamcomp/lzham_match_accel.h +146 -0
  17. data/contrib/lzham/lzhamcomp/lzham_null_threading.h +97 -0
  18. data/contrib/lzham/lzhamcomp/lzham_pthreads_threading.cpp +229 -0
  19. data/contrib/lzham/lzhamcomp/lzham_pthreads_threading.h +520 -0
  20. data/contrib/lzham/lzhamcomp/lzham_threading.h +12 -0
  21. data/contrib/lzham/lzhamcomp/lzham_win32_threading.cpp +220 -0
  22. data/contrib/lzham/lzhamcomp/lzham_win32_threading.h +368 -0
  23. data/contrib/lzham/lzhamdecomp/lzham_assert.cpp +66 -0
  24. data/contrib/lzham/lzhamdecomp/lzham_assert.h +40 -0
  25. data/contrib/lzham/lzhamdecomp/lzham_checksum.cpp +73 -0
  26. data/contrib/lzham/lzhamdecomp/lzham_checksum.h +13 -0
  27. data/contrib/lzham/lzhamdecomp/lzham_config.h +23 -0
  28. data/contrib/lzham/lzhamdecomp/lzham_core.h +264 -0
  29. data/contrib/lzham/lzhamdecomp/lzham_decomp.h +37 -0
  30. data/contrib/lzham/lzhamdecomp/lzham_helpers.h +54 -0
  31. data/contrib/lzham/lzhamdecomp/lzham_huffman_codes.cpp +262 -0
  32. data/contrib/lzham/lzhamdecomp/lzham_huffman_codes.h +14 -0
  33. data/contrib/lzham/lzhamdecomp/lzham_lzdecomp.cpp +1527 -0
  34. data/contrib/lzham/lzhamdecomp/lzham_lzdecompbase.cpp +131 -0
  35. data/contrib/lzham/lzhamdecomp/lzham_lzdecompbase.h +89 -0
  36. data/contrib/lzham/lzhamdecomp/lzham_math.h +142 -0
  37. data/contrib/lzham/lzhamdecomp/lzham_mem.cpp +284 -0
  38. data/contrib/lzham/lzhamdecomp/lzham_mem.h +112 -0
  39. data/contrib/lzham/lzhamdecomp/lzham_platform.cpp +157 -0
  40. data/contrib/lzham/lzhamdecomp/lzham_platform.h +284 -0
  41. data/contrib/lzham/lzhamdecomp/lzham_prefix_coding.cpp +351 -0
  42. data/contrib/lzham/lzhamdecomp/lzham_prefix_coding.h +146 -0
  43. data/contrib/lzham/lzhamdecomp/lzham_symbol_codec.cpp +1484 -0
  44. data/contrib/lzham/lzhamdecomp/lzham_symbol_codec.h +556 -0
  45. data/contrib/lzham/lzhamdecomp/lzham_timer.cpp +147 -0
  46. data/contrib/lzham/lzhamdecomp/lzham_timer.h +99 -0
  47. data/contrib/lzham/lzhamdecomp/lzham_traits.h +141 -0
  48. data/contrib/lzham/lzhamdecomp/lzham_types.h +97 -0
  49. data/contrib/lzham/lzhamdecomp/lzham_utils.h +58 -0
  50. data/contrib/lzham/lzhamdecomp/lzham_vector.cpp +75 -0
  51. data/contrib/lzham/lzhamdecomp/lzham_vector.h +588 -0
  52. data/contrib/lzham/lzhamlib/lzham_lib.cpp +179 -0
  53. data/examples/basic.rb +48 -0
  54. data/ext/constants.c +64 -0
  55. data/ext/decoder.c +313 -0
  56. data/ext/depend +5 -0
  57. data/ext/encoder.c +372 -0
  58. data/ext/error.c +80 -0
  59. data/ext/extconf.rb +29 -0
  60. data/ext/extlzham.c +34 -0
  61. data/ext/extlzham.h +62 -0
  62. data/gemstub.rb +22 -0
  63. data/lib/2.0/extlzham.so +0 -0
  64. data/lib/2.1/extlzham.so +0 -0
  65. data/lib/2.2/extlzham.so +0 -0
  66. data/lib/extlzham.rb +158 -0
  67. data/lib/extlzham/version.rb +5 -0
  68. data/test/test_extlzham.rb +35 -0
  69. 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