extlzham 0.0.1.PROTOTYPE3-x86-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- 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
|