10 #ifndef __PARSEBUFFER_H__
11 #define __PARSEBUFFER_H__
26 enum E_IS_EXAMPLE_USED
69 template <
class T>
class CParseBuffer:
public CSGObject
77 CParseBuffer(int32_t size = 1024);
91 Example<T>* get_free_example()
93 pthread_mutex_lock(write_lock);
94 pthread_mutex_lock(&ex_in_use_mutex[ex_write_index]);
95 while (ex_used[ex_write_index] == E_NOT_USED)
96 pthread_cond_wait(&ex_in_use_cond[ex_write_index], &ex_in_use_mutex[ex_write_index]);
97 Example<T>* ex=&ex_ring[ex_write_index];
98 pthread_mutex_unlock(&ex_in_use_mutex[ex_write_index]);
99 pthread_mutex_unlock(write_lock);
112 int32_t write_example(Example<T>* ex);
119 Example<T>* return_example_to_read();
126 Example<T>* get_unused_example();
136 int32_t copy_example(Example<T>* ex);
145 void finalize_example(
bool free_after_release);
156 void set_free_vectors_on_destruct(
bool destroy)
158 free_vectors_on_destruct = destroy;
165 bool get_free_vectors_on_destruct()
167 return free_vectors_on_destruct;
175 virtual const char* get_name()
const {
return "ParseBuffer"; }
182 virtual void inc_read_index()
184 ex_read_index=(ex_read_index + 1) % ring_size;
191 virtual void inc_write_index()
193 ex_write_index=(ex_write_index + 1) % ring_size;
204 E_IS_EXAMPLE_USED* ex_used;
206 pthread_mutex_t* ex_in_use_mutex;
208 pthread_cond_t* ex_in_use_cond;
210 pthread_mutex_t* read_lock;
212 pthread_mutex_t* write_lock;
215 int32_t ex_write_index;
217 int32_t ex_read_index;
220 bool free_vectors_on_destruct;
223 template <
class T> CParseBuffer<T>::CParseBuffer(int32_t size)
226 ex_ring = SG_CALLOC(Example<T>, ring_size);
227 ex_used = SG_MALLOC(E_IS_EXAMPLE_USED, ring_size);
228 ex_in_use_mutex = SG_MALLOC(pthread_mutex_t, ring_size);
229 ex_in_use_cond = SG_MALLOC(pthread_cond_t, ring_size);
230 read_lock = SG_MALLOC(pthread_mutex_t, 1);
231 write_lock = SG_MALLOC(pthread_mutex_t, 1);
233 SG_SINFO(
"Initialized with ring size: %d.\n", ring_size)
238 for (int32_t i=0; i<ring_size; i++)
240 ex_used[i] = E_EMPTY;
246 ex_ring[i].label = FLT_MAX;
248 pthread_cond_init(&ex_in_use_cond[i], NULL);
249 pthread_mutex_init(&ex_in_use_mutex[i], NULL);
251 pthread_mutex_init(read_lock, NULL);
252 pthread_mutex_init(write_lock, NULL);
254 free_vectors_on_destruct =
true;
257 template <
class T> CParseBuffer<T>::~CParseBuffer()
259 for (int32_t i=0; i<ring_size; i++)
261 if (ex_ring[i].fv != NULL && free_vectors_on_destruct)
263 SG_DEBUG(
"%s::~%s(): destroying examples ring vector %d at %p\n",
264 get_name(), get_name(), i, ex_ring[i].fv);
265 SG_FREE(ex_ring[i].fv);
267 pthread_mutex_destroy(&ex_in_use_mutex[i]);
268 pthread_cond_destroy(&ex_in_use_cond[i]);
272 SG_FREE(ex_in_use_mutex);
273 SG_FREE(ex_in_use_cond);
280 int32_t CParseBuffer<T>::write_example(Example<T> *ex)
282 ex_ring[ex_write_index].label = ex->label;
283 ex_ring[ex_write_index].fv = ex->fv;
284 ex_ring[ex_write_index].length = ex->length;
285 ex_used[ex_write_index] = E_NOT_USED;
292 Example<T>* CParseBuffer<T>::return_example_to_read()
294 if (ex_read_index >= 0)
295 return &ex_ring[ex_read_index];
301 Example<T>* CParseBuffer<T>::get_unused_example()
303 pthread_mutex_lock(read_lock);
306 int32_t current_index = ex_read_index;
309 pthread_mutex_lock(&ex_in_use_mutex[current_index]);
311 if (ex_used[current_index] == E_NOT_USED)
312 ex = return_example_to_read();
316 pthread_mutex_unlock(&ex_in_use_mutex[current_index]);
318 pthread_mutex_unlock(read_lock);
323 int32_t CParseBuffer<T>::copy_example(Example<T> *ex)
325 pthread_mutex_lock(write_lock);
327 int32_t current_index = ex_write_index;
329 pthread_mutex_lock(&ex_in_use_mutex[current_index]);
330 while (ex_used[ex_write_index] == E_NOT_USED)
332 pthread_cond_wait(&ex_in_use_cond[ex_write_index], &ex_in_use_mutex[ex_write_index]);
335 ret = write_example(ex);
337 pthread_mutex_unlock(&ex_in_use_mutex[current_index]);
338 pthread_mutex_unlock(write_lock);
344 void CParseBuffer<T>::finalize_example(
bool free_after_release)
346 pthread_mutex_lock(read_lock);
347 pthread_mutex_lock(&ex_in_use_mutex[ex_read_index]);
348 ex_used[ex_read_index] = E_USED;
350 if (free_after_release)
352 SG_DEBUG(
"Freeing object in ring at index %d and address: %p.\n",
353 ex_read_index, ex_ring[ex_read_index].fv);
355 SG_FREE(ex_ring[ex_read_index].fv);
356 ex_ring[ex_read_index].fv=NULL;
359 pthread_cond_signal(&ex_in_use_cond[ex_read_index]);
360 pthread_mutex_unlock(&ex_in_use_mutex[ex_read_index]);
363 pthread_mutex_unlock(read_lock);
367 #endif // HAVE_PTHREAD
368 #endif // __PARSEBUFFER_H__
all of classes and functions are contained in the shogun namespace