This file is indexed.

/usr/include/qsopt_ex/eg_memslab.h is in libqsopt-ex-dev 2.5.10.3-1+b1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
/* EGlib "Efficient General Library" provides some basic structures and
 * algorithms commons in many optimization algorithms.
 *
 * Copyright (C) 2005,2006,2007,2008,2009,2010,2011 Daniel Espinoza.
 * 
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by the
 * Free Software Foundation; either version 2.1 of the License, or (at your
 * option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
 * License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA 
 * */
/* ========================================================================= */
/** @defgroup EGmemSlab EGmemSlab
 *
 * This is a basic interface for slab pool managment. The idea comes from Slabs
 * as defined in both Linux and Solaris (see "The Slab Allocator: An
 * Object-Caching Kernel Memory Allocator", by Jeff Bonwick, Sun Microsystems),
 * the basic idea is
 * to provide pool for a specific type of object, and to store them in an
 * initialized state, so that initialization and destruction only is done while
 * growing/freeing the memory slabs, thus this approach should provide greater
 * advantages for complitated to initialize structures. and in theory
 * (althought not yet implemented) this structure can be managed so as to
 * provide a shrinkable memory managment on the fly.
 *
 * In this implementation we only allow small caches (i.e. objects must be
 * smaller than EG_SLAB_ULIMIT and internally we don't allocate objects smaller
 * than EG_SLAB_LLIMIT), 
 * within a unique memory page. We could allow in the future for more flexible
 * slabs. This implementation also uses colored slabs (see the paper for
 * further details).
 *
 * Here we can see a schematic drawing of the slab allocator structure and
 * functions:
 *
 * @version 0.9.0
 * @par History:
 * - 2011-03-01
 * 						- Make EGms_t thread-safe, i.e. a single memory pool can serve
 * 							several threads. This makes the default memory manager for GMP
 * 							thread safe as well
 * - 2010-12-27
 * 						- Add short-hand names for functions
 * - 2008-10-06
 * 						- Second implementation
 * - 2005-07-30
 * 						- First Implpementation.
 * */
/** @file
 * @ingroup EGmemSlab */
/** @addtogroup EGmemSlab */
/**  @{  */
/** @example eg_memslab.ex.c */
/* ========================================================================= */
#ifndef __EG_MEM_SLAB_H__
#define __EG_MEM_SLAB_H__

#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>

#include "eg_mem.h"
#include "eg_elist.h"

/* ========================================================================= */
/** @name EGmemSlab Parameters
 * @brief parameters for controling slab pool allocation */
/* @{ */
/** @brief control the handle of empty slabs, if set to non-zero, free unused
 * slabs as they become unused, if set to zero, keep all unused slabs until
 * #EGmemSlabPoolShrink is called */
#define EG_MSLBP_FREEFREE 1
/* @} */
/* ========================================================================= */
/* declare the slab pool structure */
struct EGmemSlabPool_t;

/* ========================================================================= */
/** @brief maximum size of the objects that can be allocated via slab. */
#define EG_SLAB_ULIMIT ((size_t)1023)
#define EG_SLAB_LLIMIT ((size_t)16)

/* ========================================================================= */
/** @brief size of the memory slabs (in bytes ) */
#define EG_SLAB_SIZE ((size_t)0x1000)

/* ========================================================================= */
/** @brief mask to detect the position of a piece of memory within a slab */
#define EG_SLAB_MASK (~(EG_SLAB_SIZE-1))

/* ========================================================================= */
/** @brief address used to check consistency if enabled */
#define EG_SLAB_POISON ((size_t)0xdeadbeef)

/* ========================================================================= */
/** @brief if set to one, enable profiling for the slab allocator */
#define EG_SLAB_PROFILE 1000

/* ========================================================================= */
/** @brief local verbose level for the slab allocator, the lower the level, the
 * more information will be printed on screen. */
#define EG_SLAB_VERBOSE 1000

/* ========================================================================= */
/** @brief local debug level for the slab allocator, the lower the level, the
 * more testing will be done. */
#define EG_SLAB_DEBUG 1000

/* ========================================================================= */
/** @brief end of list marker, note that this can not be more than 255 */
#define EG_SLAB_ENDMARK ((uint8_t)255U)

#ifndef EG_SLAB_REDUCE_TO_MALLOC
/* ========================================================================= */
/** @brief if set to one, reduce the slab pool allocator to a simple malloc
 * call */
#define EG_SLAB_REDUCE_TO_MALLOC 0
#endif


/* ========================================================================= */
/** @brief Given a pointer, return a pointer to the beginning of the containing
 * page. */
#define EG_SLAB_PAGE(__ptr) (((size_t)__ptr)&EG_SLAB_MASK)

/* ========================================================================= */
/** @brief structure that holds the information relevant to each slab
 * */
typedef struct
{
	char*base;								/**< @brief Where the data-payload start */
	size_t elem_sz;						/**< @brief byte-size of each element */
	size_t n_elem;						/**< @brief number of used elements */
	EGeList_t slab_cn;				/**< @brief Connector into the list of slabs*/
	struct EGmemSlabPool_t *pool;	/**< Pointer to the slab pool structure */
	size_t next;							/**< @brief next free element */
} EGmsbControl_t;
typedef struct
{
	EGmsbControl_t control;	/**< @brief comon base structure for slabs */
	uint8_t next_list[];		/**< @brief list of free elements, the next 
																element is next_list[0], whenever we reach a
																value of 255, it is the end of the free-list.
																*/
} EGmemSlab_t;

/* ========================================================================= */
/** @brief structure used to store a slab memory pool */
typedef struct EGmemSlabPool_t
{
	EGeList_t half;					/**< Head of the list for half-full slabs */
	EGeList_t empty;				/**< Head of the list for non used slabs */
	EGeList_t full;					/**< Head of the list for fully used slabs*/
	EGconstructor_f constr;	/**< Constructor for the local elements */
	EGdestructor_f dest;		/**< Destructor for the local elements */
	uint16_t elem_sz;				/**< Size of the elements in the slab, including 
															 extra space for pointer to next. */
	uint8_t n_elem;					/**< Total number of elements in each slab */
	uint8_t c_color;				/**< Last used color while creating slabs. */
	uint8_t max_color;			/**< Maximum valid value for colors in this pool */
	uint8_t freefree:1;			/**< if non-zero, free non-used slabs */
	uint8_t pad1:7;					/**< padding */
	uint16_t pad2;					/**< padding */
	char const *file;				/**< File where the structure was initialized */
	char const *func;				/**< Function where the structure was initialized */
	int line;								/**< Line where the structure was initialized */
	uint64_t real_sz;				/**< Actual size of the elements asked by the user */
	uint64_t n_slabs;				/**< Number of slabs */
	uint64_t n_tot;					/**< Total number of elements in use by the user */
	uint64_t max_tot;				/**< Maximum number of elements allocated */
	uint64_t max_slabs;			/**< Maximum number of slabs used */
	uint64_t ncals;					/**< number to alloc calls */
	uint64_t n_allocs;			/**< number slab alloc calls */
	#if HAVE_EG_THREAD
	pthread_mutex_t mt;			/**< mutex for memory slab manager */
	#endif
}
EGmemSlabPool_t;

/* ========================================================================= */
/** @brief slab lock/unlock macros */
#if HAVE_EG_THREAD
#define __EGmspLock(__slab) pthread_mutex_lock(&(__slab->mt))
#define __EGmspUnlock(__slab) pthread_mutex_unlock(&(__slab->mt))
#else
#define __EGmspLock(__slab)
#define __EGmspUnlock(__slab)
#endif
/* ========================================================================= */
/** @brief display given slab structure 
 * @param slab what to display
 * */
void EGmemSlabDisplay(const EGmemSlab_t*const slab);

/* ========================================================================= */
/** @brief display given pool structure
 * @param pool what to display
 * */
void EGmemSlabPoolDisplay(const EGmemSlabPool_t*const pool);

/* ========================================================================= */
/** @brief given a piece of memory that should be within a slab, return the
 * pointer to the related slab structure, remember that the slab structure is
 * at the beggining of the page. */
#define EGmemSlabGetSlab(__ptr) \
		((EGmemSlab_t*)(EG_SLAB_PAGE(__ptr)))

/* ========================================================================= */
/** @brief initialize a slab structure. This include calling the constructor
 * for all elements in the slab. Note that this function asumes that all memory
 * has been previously set to NULL. It will also place this slab in the list 
 * of empty slabs in the given pool.
 * @param slab pointer within the memory range of the slab to be initialized.
 * @param __Pool Slab __Pool where this slab will bellong from. The slab pool
 * should be initialized (i.e. should have a constructor and destructor, and an
 * element size set.
 * */
void __EGmemSlabInit( EGmemSlab_t*const slab,
										EGmemSlabPool_t*const __Pool);
/* ========================================================================= */
/** @brief given an initialized slab, clear all internally allocated memory,
 * and leave the slab ready to be freed by 'free', this include calling the
 * destructor for all elements in the slab.
 * @param slab pointer to an area of the slab memory to be clear.
 * @note If debugging is enabled, then all fields will be poisoned so that
 * subsequent use of this structure will fail (but for the free call). Also, if
 * debugging is enabled, we will check that the slab has no element in use.
 * */
void EGmemSlabClear( EGmemSlab_t*const slab);

/* ========================================================================= */
/** @brief Given a non-full slab, extract a pointer to the next unused element
 * in the slab, and update all internal data. and if it becomes full, then move
 * it to the full list within the pool. Also, if debugging, poison the pointer
 * to the enext element in the returned element. If the slab is not full, and
 * the number of active elements is one, then move the slab to the half-full
 * slab list in the pool.
 * @param slab pointer within a slab memory.
 * @return pointer to a void* of initialized memory by the given contructor in
 * the slab pool.
 * */
#define EGmemSlabPopElement(slab) ({\
	EGmemSlab_t*const _EGmSlb = EGmemSlabGetSlab(slab);\
	EGmemSlabPool_t*const _EGPlRf = _EGmSlb->control.pool;\
	const size_t _EGmSlb_esz = _EGmSlb->control.elem_sz;\
	const size_t _EGmSlb_ne = _EGmSlb->control.next;\
	const size_t _EGmSlb_nn = _EGmSlb->next_list[_EGmSlb_ne];\
	void*const _EGelem = (void*)(_EGmSlb_ne*_EGmSlb_esz + _EGmSlb->control.base);\
	/* now update the slab */\
	_EGmSlb->control.n_elem++;\
	_EGmSlb->control.next = _EGmSlb_nn;\
	EXITL(EG_SLAB_DEBUG,_EGmSlb_ne == EG_SLAB_ENDMARK, "Allocating from full slab");\
	/* if the slab is full, move it to full list */\
	if(_EGmSlb_nn == EG_SLAB_ENDMARK){\
		EGeListMoveAfter(&(_EGmSlb->control.slab_cn),&(_EGPlRf->full));}\
	/* if the slab is first-time used, move to half list */\
	else if(_EGmSlb->control.n_elem == 1U){\
		EGeListMoveAfter(&(_EGmSlb->control.slab_cn),&(_EGPlRf->half));}\
	/* return the element */\
	_EGelem;})

/* ========================================================================= */
/** @brief Given an used object within a slab, give it back to the slab for
 * future use.
 * @param __ptr pointer to the element to be given back to its containing slab.
 * */
#define EGmemSlabPushElement(__ptr) do{\
	char*const _EGmsbPtr = (char*)(__ptr);\
	EGmemSlab_t*const _EGmSlb = EGmemSlabGetSlab(_EGmsbPtr);\
	EGmemSlabPool_t*const _EGPlRf = _EGmSlb->control.pool;\
	__EGmspLock(_EGPlRf);{\
	const size_t _EGmSlb_esz = _EGmSlb->control.elem_sz;\
	const size_t _EGmSlb_ne = _EGmSlb->control.next;\
	const size_t _EGmSlb_nn = ((_EGmsbPtr) - _EGmSlb->control.base)/_EGmSlb_esz;\
	/* if debugging, check for poison in the pointer to the next element in the \
	 * given element */\
	EXITL(EG_SLAB_DEBUG, !_EGmSlb->control.n_elem, "freeing from an empty slab");\
	/* now actually put the element into the slab */\
	_EGmSlb->control.n_elem--;\
	_EGmSlb->control.next = _EGmSlb_nn;\
	_EGmSlb->next_list[_EGmSlb_nn] = _EGmSlb_ne;\
	__EGmsbUPD2(_EGPlRf);\
	/* if the slab is now not being used, update accordingly */\
	if(_EGmSlb_ne == EG_SLAB_ENDMARK){\
		EGeListMoveAfter(&(_EGmSlb->control.slab_cn),&(_EGPlRf->half));}\
	else if(!_EGmSlb->control.n_elem){\
		if(_EGPlRf->freefree){\
			EGmemSlabClear(_EGmSlb);\
			free((void*)_EGmSlb);}\
		else{\
			EGeListMoveAfter(&(_EGmSlb->control.slab_cn),&(_EGPlRf->empty));}}}\
	__EGmspUnlock(_EGPlRf);\
	}while(0)

/* ========================================================================= */
/** @brief initialize a slab pool as an empty pool for elements of the given
 * size, and with te given constructor and destructors. 
 * @param constr_fn constructor fnctioin for the elements to be stored in the
 * pool.
 * @param dest_fn destructor function for the elements to be stored in the
 * pool.
 * @param pool pointer to the slab pool to initialize.
 * @param sz (real) size (in bytes) of the elements to be hold. in the pool.
 * This means that sz is the result of sizeof(TYPE), where TYPE is the
 * structure to be pooled. */
#define EGmemSlabPoolInit(pool, sz, constr_fn, dest_fn) \
				__EGmemSlabPoolInit(pool, sz, constr_fn, dest_fn, \
														__FILE__, __func__, __LINE__)
void __EGmemSlabPoolInit( EGmemSlabPool_t*const pool,
													const size_t sz,
													EGconstructor_f constr_fn,
													EGdestructor_f dest_fn,
													const char*const file,
													const char*const func,
													const int line);
/* ========================================================================= */
/** @brief clear a slab pool and all internal sub-structures and data, no
 * further calls to this structure are posible after this (but for freeing the
 * memory containing this data, or to re-initialize it).
 * @param __Pool slab pool to be cleared.
 * */
void EGmemSlabPoolClear(EGmemSlabPool_t*const __Pool);
/* ========================================================================= */
/** @brief add one to the given pointer, if profiling is enabled, otherwise, do
 * nothing */
#if EG_SLAB_PROFILE <= DEBUG
#define __EGmsbUPD1(__pool) do{\
	__pool->ncals++;\
	__pool->n_tot++;\
	if(__pool->max_tot < __pool->n_tot) __pool->max_tot = __pool->n_tot;}while(0)
#define __EGmsbUPD2(__pool) __pool->n_tot--
#else
#define __EGmsbUPD1(__pool)
#define __EGmsbUPD2(__pool)
#endif

/* ========================================================================= */
/** @brief Given a slab pool, return an element from the pool. 
 * @param __Pool slab pool from where we will get the memory. 
 * @return pointer to an initialize element. */
#if EG_SLAB_REDUCE_TO_MALLOC
#define EGmemSlabPoolAlloc(__Pool) ({\
	EGmemSlabPool_t*const _EGmPl = (__Pool);\
	void*_EGmb = EGmalloc(_EGmPl->elem_sz+sizeof(void*));\
	void**_EGpt = (void**)_EGmb;\
	__EGmsbUPD1(_EGmPl);\
	(*_EGpt) = _EGmPl;\
	_EGmb=((void*)(_EGpt+1));\
	if(_EGmPl->constr) _EGmPl->constr(_EGmb);\
	_EGmb;})
#else
#define EGmemSlabPoolAlloc(__Pool) ({\
	EGmemSlabPool_t*const _EGmPl = (__Pool);\
	void* _EGSmbRf = 0;\
	void* _EGrptr = 0;\
	int __EGmPlerr=0;\
	__EGmspLock(_EGmPl);\
	__EGmsbUPD1(_EGmPl);\
	if(!EGeListIsEmpty(&(_EGmPl->half))){ _EGSmbRf = _EGmPl->half.next;}\
	else if(!EGeListIsEmpty(&(_EGmPl->empty))){ _EGSmbRf = _EGmPl->empty.next;}\
	else{\
		if((__EGmPlerr=posix_memalign(&_EGSmbRf,EG_SLAB_SIZE,EG_SLAB_SIZE))){\
			EXIT(1,"posix_memalign falied with code %d, error %s",__EGmPlerr,\
					strerror(__EGmPlerr));}\
		__EGmemSlabInit(_EGSmbRf,_EGmPl);}\
	_EGrptr = EGmemSlabPopElement(_EGSmbRf);\
	MESSAGE(EG_SLAB_VERBOSE,"Returning %p",_EGrptr);\
	__EGmspUnlock(_EGmPl);\
	_EGrptr;})
#endif

/* ========================================================================= */
/** @brief Given a pointer to an element allocated through a slab pool, give it
 * back to the pool.
 * @param __ptr pointer to be returned to the pool.
 * */
#if EG_SLAB_REDUCE_TO_MALLOC
#define EGmemSlabPoolFree(__ptr) ({\
	void**_EGptr = ((void**)(__ptr))-1;\
	EGmemSlabPool_t*const _EGmPl = (EGmemSlabPool_t*)(*_EGptr);\
	__EGmsbUPD2(_EGmPl);\
	if(_EGmPl->dest) _EGmPl->dest(((void*)(_EGptr+1)));\
	EGfree(_EGptr);})
#else
#define EGmemSlabPoolFree(__ptr) EGmemSlabPushElement(__ptr)
#endif

/* ========================================================================= */
/** @brief Given a slab pool, free all unused slabs 
 * @param pool slab pool to be shrinked. */
void EGmemSlabPoolShrink(EGmemSlabPool_t*const pool);

/* ========================================================================= */
/** @brief set parameters for a slab pool */
int EGmemSlabPoolSetParam(EGmemSlabPool_t*const pool,
													const int param,
													const int val);
/* ========================================================================= */
/** @brief short names for common functions */
#define EGmsAlloc  EGmemSlabPoolAlloc
#define EGmsFree   EGmemSlabPoolFree
#define EGmsInit   EGmemSlabPoolInit
#define EGmsClear  EGmemSlabPoolClear
#define EGms_t     EGmemSlabPool_t
#define EGmsShrink EGmemSlabPoolShrink
/* ========================================================================= */
/* end of eg_memslab.h */
/**  @}  */
#endif