fcb3d2bfe1fd32083ec5401f11864df42a0e41bb
1 /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
16 const uint64_t redzone_pattern
= 0xdeadbeefcafebabe;
20 const int initial_pool_size
= 64;
22 cache_t
* cache_create(const char *name
, size_t bufsize
, size_t align
,
23 cache_constructor_t
* constructor
,
24 cache_destructor_t
* destructor
) {
25 cache_t
* ret
= calloc(1, sizeof(cache_t
));
26 char* nm
= strdup(name
);
27 void** ptr
= calloc(initial_pool_size
, sizeof(void*));
28 if (ret
== NULL
|| nm
== NULL
|| ptr
== NULL
||
29 pthread_mutex_init(&ret
->mutex
, NULL
) == -1) {
38 ret
->freetotal
= initial_pool_size
;
39 ret
->constructor
= constructor
;
40 ret
->destructor
= destructor
;
43 ret
->bufsize
= bufsize
+ 2 * sizeof(redzone_pattern
);
45 ret
->bufsize
= bufsize
;
51 static inline void* get_object(void *ptr
) {
60 void cache_destroy(cache_t
*cache
) {
61 while (cache
->freecurr
> 0) {
62 void *ptr
= cache
->ptr
[--cache
->freecurr
];
63 if (cache
->destructor
) {
64 cache
->destructor(get_object(ptr
), NULL
);
70 pthread_mutex_destroy(&cache
->mutex
);
74 void* cache_alloc(cache_t
*cache
) {
77 pthread_mutex_lock(&cache
->mutex
);
78 if (cache
->freecurr
> 0) {
79 ret
= cache
->ptr
[--cache
->freecurr
];
80 object
= get_object(ret
);
82 object
= ret
= malloc(cache
->bufsize
);
84 object
= get_object(ret
);
86 if (cache
->constructor
!= NULL
&&
87 cache
->constructor(object
, NULL
, 0) != 0) {
93 pthread_mutex_unlock(&cache
->mutex
);
97 /* add a simple form of buffer-check */
99 *pre
= redzone_pattern
;
101 memcpy(((char*)ret
) + cache
->bufsize
- (2 * sizeof(redzone_pattern
)),
102 &redzone_pattern
, sizeof(redzone_pattern
));
109 void cache_free(cache_t
*cache
, void *ptr
) {
110 pthread_mutex_lock(&cache
->mutex
);
113 /* validate redzone... */
114 if (memcmp(((char*)ptr
) + cache
->bufsize
- (2 * sizeof(redzone_pattern
)),
115 &redzone_pattern
, sizeof(redzone_pattern
)) != 0) {
118 pthread_mutex_unlock(&cache
->mutex
);
123 if (*pre
!= redzone_pattern
) {
126 pthread_mutex_unlock(&cache
->mutex
);
131 if (cache
->freecurr
< cache
->freetotal
) {
132 cache
->ptr
[cache
->freecurr
++] = ptr
;
134 /* try to enlarge free connections array */
135 size_t newtotal
= cache
->freetotal
* 2;
136 void **new_free
= realloc(cache
->ptr
, sizeof(char *) * newtotal
);
138 cache
->freetotal
= newtotal
;
139 cache
->ptr
= new_free
;
140 cache
->ptr
[cache
->freecurr
++] = ptr
;
142 if (cache
->destructor
) {
143 cache
->destructor(ptr
, NULL
);
149 pthread_mutex_unlock(&cache
->mutex
);