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,146 @@
|
|
1
|
+
// File: lzham_match_accel.h
|
2
|
+
// See Copyright Notice and license at the end of include/lzham.h
|
3
|
+
#pragma once
|
4
|
+
#include "lzham_lzbase.h"
|
5
|
+
#include "lzham_threading.h"
|
6
|
+
|
7
|
+
namespace lzham
|
8
|
+
{
|
9
|
+
const uint cMatchAccelMaxSupportedProbes = 128;
|
10
|
+
|
11
|
+
struct node
|
12
|
+
{
|
13
|
+
uint m_left;
|
14
|
+
uint m_right;
|
15
|
+
};
|
16
|
+
|
17
|
+
LZHAM_DEFINE_BITWISE_MOVABLE(node);
|
18
|
+
|
19
|
+
#pragma pack(push, 1)
|
20
|
+
struct dict_match
|
21
|
+
{
|
22
|
+
uint m_dist;
|
23
|
+
uint16 m_len;
|
24
|
+
|
25
|
+
inline uint get_dist() const { return m_dist & 0x7FFFFFFF; }
|
26
|
+
inline uint get_len() const { return m_len + 2; }
|
27
|
+
inline bool is_last() const { return (int)m_dist < 0; }
|
28
|
+
};
|
29
|
+
#pragma pack(pop)
|
30
|
+
|
31
|
+
LZHAM_DEFINE_BITWISE_MOVABLE(dict_match);
|
32
|
+
|
33
|
+
class search_accelerator
|
34
|
+
{
|
35
|
+
public:
|
36
|
+
search_accelerator();
|
37
|
+
|
38
|
+
// If all_matches is true, the match finder returns all found matches with no filtering.
|
39
|
+
// Otherwise, the finder will tend to return lists of matches with mostly unique lengths.
|
40
|
+
// For each length, it will discard matches with worse distances (in the coding sense).
|
41
|
+
bool init(CLZBase* pLZBase, task_pool* pPool, uint max_helper_threads, uint max_dict_size, uint max_matches, bool all_matches, uint max_probes);
|
42
|
+
|
43
|
+
void reset();
|
44
|
+
void flush();
|
45
|
+
|
46
|
+
inline uint get_max_dict_size() const { return m_max_dict_size; }
|
47
|
+
inline uint get_max_dict_size_mask() const { return m_max_dict_size_mask; }
|
48
|
+
inline uint get_cur_dict_size() const { return m_cur_dict_size; }
|
49
|
+
|
50
|
+
inline uint get_lookahead_pos() const { return m_lookahead_pos; }
|
51
|
+
inline uint get_lookahead_size() const { return m_lookahead_size; }
|
52
|
+
|
53
|
+
inline uint get_char(int delta_pos) const { return m_dict[(m_lookahead_pos + delta_pos) & m_max_dict_size_mask]; }
|
54
|
+
inline uint get_char(uint cur_dict_pos, int delta_pos) const { return m_dict[(cur_dict_pos + delta_pos) & m_max_dict_size_mask]; }
|
55
|
+
inline const uint8* get_ptr(uint pos) const { return &m_dict[pos]; }
|
56
|
+
|
57
|
+
uint get_max_helper_threads() const { return m_max_helper_threads; }
|
58
|
+
|
59
|
+
inline uint operator[](uint pos) const { return m_dict[pos]; }
|
60
|
+
|
61
|
+
uint get_max_add_bytes() const;
|
62
|
+
bool add_bytes_begin(uint num_bytes, const uint8* pBytes);
|
63
|
+
inline atomic32_t get_num_completed_helper_threads() const { return m_num_completed_helper_threads; }
|
64
|
+
void add_bytes_end();
|
65
|
+
|
66
|
+
// Returns the lookahead's raw position/size/dict_size at the time add_bytes_begin() is called.
|
67
|
+
inline uint get_fill_lookahead_pos() const { return m_fill_lookahead_pos; }
|
68
|
+
inline uint get_fill_lookahead_size() const { return m_fill_lookahead_size; }
|
69
|
+
inline uint get_fill_dict_size() const { return m_fill_dict_size; }
|
70
|
+
|
71
|
+
uint get_len2_match(uint lookahead_ofs);
|
72
|
+
dict_match* find_matches(uint lookahead_ofs, bool spin = true);
|
73
|
+
|
74
|
+
void advance_bytes(uint num_bytes);
|
75
|
+
|
76
|
+
LZHAM_FORCE_INLINE uint get_match_len(uint lookahead_ofs, int dist, uint max_match_len, uint start_match_len = 0) const
|
77
|
+
{
|
78
|
+
LZHAM_ASSERT(lookahead_ofs < m_lookahead_size);
|
79
|
+
LZHAM_ASSERT(start_match_len <= max_match_len);
|
80
|
+
LZHAM_ASSERT(max_match_len <= (get_lookahead_size() - lookahead_ofs));
|
81
|
+
|
82
|
+
const int find_dict_size = m_cur_dict_size + lookahead_ofs;
|
83
|
+
if (dist > find_dict_size)
|
84
|
+
return 0;
|
85
|
+
|
86
|
+
const uint comp_pos = static_cast<uint>((m_lookahead_pos + lookahead_ofs - dist) & m_max_dict_size_mask);
|
87
|
+
const uint lookahead_pos = (m_lookahead_pos + lookahead_ofs) & m_max_dict_size_mask;
|
88
|
+
|
89
|
+
const uint8* pComp = &m_dict[comp_pos];
|
90
|
+
const uint8* pLookahead = &m_dict[lookahead_pos];
|
91
|
+
|
92
|
+
uint match_len;
|
93
|
+
for (match_len = start_match_len; match_len < max_match_len; match_len++)
|
94
|
+
if (pComp[match_len] != pLookahead[match_len])
|
95
|
+
break;
|
96
|
+
|
97
|
+
return match_len;
|
98
|
+
}
|
99
|
+
|
100
|
+
public:
|
101
|
+
CLZBase* m_pLZBase;
|
102
|
+
task_pool* m_pTask_pool;
|
103
|
+
uint m_max_helper_threads;
|
104
|
+
|
105
|
+
uint m_max_dict_size;
|
106
|
+
uint m_max_dict_size_mask;
|
107
|
+
|
108
|
+
uint m_lookahead_pos;
|
109
|
+
uint m_lookahead_size;
|
110
|
+
|
111
|
+
uint m_cur_dict_size;
|
112
|
+
|
113
|
+
lzham::vector<uint8> m_dict;
|
114
|
+
|
115
|
+
enum { cHashSize = 65536 };
|
116
|
+
lzham::vector<uint> m_hash;
|
117
|
+
lzham::vector<node> m_nodes;
|
118
|
+
|
119
|
+
lzham::vector<dict_match> m_matches;
|
120
|
+
lzham::vector<atomic32_t> m_match_refs;
|
121
|
+
|
122
|
+
lzham::vector<uint8> m_hash_thread_index;
|
123
|
+
|
124
|
+
enum { cDigramHashSize = 4096 };
|
125
|
+
lzham::vector<uint> m_digram_hash;
|
126
|
+
lzham::vector<uint> m_digram_next;
|
127
|
+
|
128
|
+
uint m_fill_lookahead_pos;
|
129
|
+
uint m_fill_lookahead_size;
|
130
|
+
uint m_fill_dict_size;
|
131
|
+
|
132
|
+
uint m_max_probes;
|
133
|
+
uint m_max_matches;
|
134
|
+
|
135
|
+
bool m_all_matches;
|
136
|
+
|
137
|
+
volatile atomic32_t m_next_match_ref;
|
138
|
+
|
139
|
+
volatile atomic32_t m_num_completed_helper_threads;
|
140
|
+
|
141
|
+
void find_all_matches_callback(uint64 data, void* pData_ptr);
|
142
|
+
bool find_all_matches(uint num_bytes);
|
143
|
+
bool find_len2_matches();
|
144
|
+
};
|
145
|
+
|
146
|
+
} // namespace lzham
|
@@ -0,0 +1,97 @@
|
|
1
|
+
// File: lzham_task_pool_null.h
|
2
|
+
// See Copyright Notice and license at the end of include/lzham.h
|
3
|
+
#pragma once
|
4
|
+
|
5
|
+
namespace lzham
|
6
|
+
{
|
7
|
+
class semaphore
|
8
|
+
{
|
9
|
+
LZHAM_NO_COPY_OR_ASSIGNMENT_OP(semaphore);
|
10
|
+
|
11
|
+
public:
|
12
|
+
inline semaphore(long initialCount = 0, long maximumCount = 1, const char* pName = NULL)
|
13
|
+
{
|
14
|
+
(void)initialCount, (void)maximumCount, (void)pName;
|
15
|
+
}
|
16
|
+
|
17
|
+
inline ~semaphore()
|
18
|
+
{
|
19
|
+
}
|
20
|
+
|
21
|
+
inline void release(long releaseCount = 1, long *pPreviousCount = NULL)
|
22
|
+
{
|
23
|
+
(void)releaseCount, (void)pPreviousCount;
|
24
|
+
}
|
25
|
+
|
26
|
+
inline bool wait(uint32 milliseconds = UINT32_MAX)
|
27
|
+
{
|
28
|
+
(void)milliseconds;
|
29
|
+
return true;
|
30
|
+
}
|
31
|
+
};
|
32
|
+
|
33
|
+
class task_pool
|
34
|
+
{
|
35
|
+
public:
|
36
|
+
inline task_pool() { }
|
37
|
+
inline task_pool(uint num_threads) { (void)num_threads; }
|
38
|
+
inline ~task_pool() { }
|
39
|
+
|
40
|
+
inline bool init(uint num_threads) { (void)num_threads; return true; }
|
41
|
+
inline void deinit();
|
42
|
+
|
43
|
+
inline uint get_num_threads() const { return 0; }
|
44
|
+
inline uint get_num_outstanding_tasks() const { return 0; }
|
45
|
+
|
46
|
+
// C-style task callback
|
47
|
+
typedef void (*task_callback_func)(uint64 data, void* pData_ptr);
|
48
|
+
inline bool queue_task(task_callback_func pFunc, uint64 data = 0, void* pData_ptr = NULL)
|
49
|
+
{
|
50
|
+
pFunc(data, pData_ptr);
|
51
|
+
return true;
|
52
|
+
}
|
53
|
+
|
54
|
+
class executable_task
|
55
|
+
{
|
56
|
+
public:
|
57
|
+
virtual void execute_task(uint64 data, void* pData_ptr) = 0;
|
58
|
+
};
|
59
|
+
|
60
|
+
// It's the caller's responsibility to delete pObj within the execute_task() method, if needed!
|
61
|
+
inline bool queue_task(executable_task* pObj, uint64 data = 0, void* pData_ptr = NULL)
|
62
|
+
{
|
63
|
+
pObj->execute_task(data, pData_ptr);
|
64
|
+
return true;
|
65
|
+
}
|
66
|
+
|
67
|
+
template<typename S, typename T>
|
68
|
+
inline bool queue_object_task(S* pObject, T pObject_method, uint64 data = 0, void* pData_ptr = NULL)
|
69
|
+
{
|
70
|
+
(pObject->*pObject_method)(data, pData_ptr);
|
71
|
+
return true;
|
72
|
+
}
|
73
|
+
|
74
|
+
template<typename S, typename T>
|
75
|
+
inline bool queue_multiple_object_tasks(S* pObject, T pObject_method, uint64 first_data, uint num_tasks, void* pData_ptr = NULL)
|
76
|
+
{
|
77
|
+
for (uint i = 0; i < num_tasks; i++)
|
78
|
+
{
|
79
|
+
(pObject->*pObject_method)(first_data + i, pData_ptr);
|
80
|
+
}
|
81
|
+
return true;
|
82
|
+
}
|
83
|
+
|
84
|
+
void join() { }
|
85
|
+
};
|
86
|
+
|
87
|
+
inline void lzham_sleep(unsigned int milliseconds)
|
88
|
+
{
|
89
|
+
(void)milliseconds;
|
90
|
+
}
|
91
|
+
|
92
|
+
inline uint lzham_get_max_helper_threads()
|
93
|
+
{
|
94
|
+
return 0;
|
95
|
+
}
|
96
|
+
|
97
|
+
} // namespace lzham
|
@@ -0,0 +1,229 @@
|
|
1
|
+
// File: lzham_task_pool_pthreads.cpp
|
2
|
+
//
|
3
|
+
// Copyright (c) 2009-2010 Richard Geldreich, Jr. <richgel99@gmail.com>
|
4
|
+
//
|
5
|
+
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
// of this software and associated documentation files (the "Software"), to deal
|
7
|
+
// in the Software without restriction, including without limitation the rights
|
8
|
+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
// copies of the Software, and to permit persons to whom the Software is
|
10
|
+
// furnished to do so, subject to the following conditions:
|
11
|
+
//
|
12
|
+
// The above copyright notice and this permission notice shall be included in
|
13
|
+
// all copies or substantial portions of the Software.
|
14
|
+
//
|
15
|
+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
// THE SOFTWARE.
|
22
|
+
#include "lzham_core.h"
|
23
|
+
#include "lzham_pthreads_threading.h"
|
24
|
+
#include "lzham_timer.h"
|
25
|
+
|
26
|
+
#ifdef WIN32
|
27
|
+
#include <process.h>
|
28
|
+
#endif
|
29
|
+
|
30
|
+
#if defined(__GNUC__) && !defined(__APPLE__) && !defined(__MINGW32__) && !defined(__FreeBSD__)
|
31
|
+
#include <sys/sysinfo.h>
|
32
|
+
#endif
|
33
|
+
|
34
|
+
#if LZHAM_USE_PTHREADS_API
|
35
|
+
|
36
|
+
#ifdef WIN32
|
37
|
+
#pragma comment(lib, "../ext/libpthread/lib/pthreadVC2.lib")
|
38
|
+
#endif
|
39
|
+
|
40
|
+
namespace lzham
|
41
|
+
{
|
42
|
+
task_pool::task_pool() :
|
43
|
+
m_num_threads(0),
|
44
|
+
m_tasks_available(0, 32767),
|
45
|
+
m_num_outstanding_tasks(0),
|
46
|
+
m_exit_flag(false)
|
47
|
+
{
|
48
|
+
utils::zero_object(m_threads);
|
49
|
+
}
|
50
|
+
|
51
|
+
task_pool::task_pool(uint num_threads) :
|
52
|
+
m_num_threads(0),
|
53
|
+
m_tasks_available(0, 32767),
|
54
|
+
m_num_outstanding_tasks(0),
|
55
|
+
m_exit_flag(false)
|
56
|
+
{
|
57
|
+
utils::zero_object(m_threads);
|
58
|
+
|
59
|
+
bool status = init(num_threads);
|
60
|
+
LZHAM_VERIFY(status);
|
61
|
+
}
|
62
|
+
|
63
|
+
task_pool::~task_pool()
|
64
|
+
{
|
65
|
+
deinit();
|
66
|
+
}
|
67
|
+
|
68
|
+
bool task_pool::init(uint num_threads)
|
69
|
+
{
|
70
|
+
LZHAM_ASSERT(num_threads <= cMaxThreads);
|
71
|
+
num_threads = math::minimum<uint>(num_threads, cMaxThreads);
|
72
|
+
|
73
|
+
deinit();
|
74
|
+
|
75
|
+
bool succeeded = true;
|
76
|
+
|
77
|
+
m_num_threads = 0;
|
78
|
+
while (m_num_threads < num_threads)
|
79
|
+
{
|
80
|
+
int status = pthread_create(&m_threads[m_num_threads], NULL, thread_func, this);
|
81
|
+
if (status)
|
82
|
+
{
|
83
|
+
succeeded = false;
|
84
|
+
break;
|
85
|
+
}
|
86
|
+
|
87
|
+
m_num_threads++;
|
88
|
+
}
|
89
|
+
|
90
|
+
if (!succeeded)
|
91
|
+
{
|
92
|
+
deinit();
|
93
|
+
return false;
|
94
|
+
}
|
95
|
+
|
96
|
+
return true;
|
97
|
+
}
|
98
|
+
|
99
|
+
void task_pool::deinit()
|
100
|
+
{
|
101
|
+
if (m_num_threads)
|
102
|
+
{
|
103
|
+
join();
|
104
|
+
|
105
|
+
atomic_exchange32(&m_exit_flag, true);
|
106
|
+
|
107
|
+
m_tasks_available.release(m_num_threads);
|
108
|
+
|
109
|
+
for (uint i = 0; i < m_num_threads; i++)
|
110
|
+
pthread_join(m_threads[i], NULL);
|
111
|
+
|
112
|
+
m_num_threads = 0;
|
113
|
+
|
114
|
+
atomic_exchange32(&m_exit_flag, false);
|
115
|
+
}
|
116
|
+
|
117
|
+
m_task_stack.clear();
|
118
|
+
m_num_outstanding_tasks = 0;
|
119
|
+
}
|
120
|
+
|
121
|
+
bool task_pool::queue_task(task_callback_func pFunc, uint64 data, void* pData_ptr)
|
122
|
+
{
|
123
|
+
LZHAM_ASSERT(m_num_threads);
|
124
|
+
LZHAM_ASSERT(pFunc);
|
125
|
+
|
126
|
+
task tsk;
|
127
|
+
tsk.m_callback = pFunc;
|
128
|
+
tsk.m_data = data;
|
129
|
+
tsk.m_pData_ptr = pData_ptr;
|
130
|
+
tsk.m_flags = 0;
|
131
|
+
|
132
|
+
if (!m_task_stack.try_push(tsk))
|
133
|
+
return false;
|
134
|
+
|
135
|
+
atomic_increment32(&m_num_outstanding_tasks);
|
136
|
+
|
137
|
+
m_tasks_available.release(1);
|
138
|
+
|
139
|
+
return true;
|
140
|
+
}
|
141
|
+
|
142
|
+
// It's the object's responsibility to delete pObj within the execute_task() method, if needed!
|
143
|
+
bool task_pool::queue_task(executable_task* pObj, uint64 data, void* pData_ptr)
|
144
|
+
{
|
145
|
+
LZHAM_ASSERT(m_num_threads);
|
146
|
+
LZHAM_ASSERT(pObj);
|
147
|
+
|
148
|
+
task tsk;
|
149
|
+
tsk.m_pObj = pObj;
|
150
|
+
tsk.m_data = data;
|
151
|
+
tsk.m_pData_ptr = pData_ptr;
|
152
|
+
tsk.m_flags = cTaskFlagObject;
|
153
|
+
|
154
|
+
if (!m_task_stack.try_push(tsk))
|
155
|
+
return false;
|
156
|
+
|
157
|
+
atomic_increment32(&m_num_outstanding_tasks);
|
158
|
+
|
159
|
+
m_tasks_available.release(1);
|
160
|
+
|
161
|
+
return true;
|
162
|
+
}
|
163
|
+
|
164
|
+
void task_pool::process_task(task& tsk)
|
165
|
+
{
|
166
|
+
if (tsk.m_flags & cTaskFlagObject)
|
167
|
+
tsk.m_pObj->execute_task(tsk.m_data, tsk.m_pData_ptr);
|
168
|
+
else
|
169
|
+
tsk.m_callback(tsk.m_data, tsk.m_pData_ptr);
|
170
|
+
|
171
|
+
atomic_decrement32(&m_num_outstanding_tasks);
|
172
|
+
}
|
173
|
+
|
174
|
+
void task_pool::join()
|
175
|
+
{
|
176
|
+
task tsk;
|
177
|
+
while (atomic_add32(&m_num_outstanding_tasks, 0) > 0)
|
178
|
+
{
|
179
|
+
if (m_task_stack.pop(tsk))
|
180
|
+
{
|
181
|
+
process_task(tsk);
|
182
|
+
}
|
183
|
+
else
|
184
|
+
{
|
185
|
+
lzham_sleep(1);
|
186
|
+
}
|
187
|
+
}
|
188
|
+
}
|
189
|
+
|
190
|
+
void * task_pool::thread_func(void *pContext)
|
191
|
+
{
|
192
|
+
task_pool* pPool = static_cast<task_pool*>(pContext);
|
193
|
+
task tsk;
|
194
|
+
|
195
|
+
for ( ; ; )
|
196
|
+
{
|
197
|
+
if (!pPool->m_tasks_available.wait())
|
198
|
+
break;
|
199
|
+
|
200
|
+
if (pPool->m_exit_flag)
|
201
|
+
break;
|
202
|
+
|
203
|
+
if (pPool->m_task_stack.pop(tsk))
|
204
|
+
{
|
205
|
+
pPool->process_task(tsk);
|
206
|
+
}
|
207
|
+
}
|
208
|
+
|
209
|
+
return NULL;
|
210
|
+
}
|
211
|
+
|
212
|
+
uint lzham_get_max_helper_threads()
|
213
|
+
{
|
214
|
+
#if defined(__APPLE__) || defined(__FreeBSD__)
|
215
|
+
int num_procs = static_cast<int>(sysconf(_SC_NPROCESSORS_ONLN));
|
216
|
+
return (num_procs >= 1) ? (num_procs - 1) : 0;
|
217
|
+
#elif (1)
|
218
|
+
uint num_procs = get_nprocs();
|
219
|
+
return num_procs ? (num_procs - 1) : 0;
|
220
|
+
#else
|
221
|
+
printf("TODO: lzham_get_max_helper_threads(): Implement system specific func to determine the max # of helper threads\n");
|
222
|
+
// Just assume a dual-core machine.
|
223
|
+
return 1;
|
224
|
+
#endif
|
225
|
+
}
|
226
|
+
|
227
|
+
} // namespace lzham
|
228
|
+
|
229
|
+
#endif // LZHAM_USE_PTHREADS_API
|