FS-10052: [libks] Add experimental ref counting to ks_pool #resolve
This commit is contained in:
parent
23c9605efb
commit
d452db8d08
|
@ -67,6 +67,8 @@ typedef enum {
|
|||
#define KS_POOL_FUNC_CALLOC 4 /* ks_pool_calloc function called */
|
||||
#define KS_POOL_FUNC_FREE 5 /* ks_pool_free function called */
|
||||
#define KS_POOL_FUNC_RESIZE 6 /* ks_pool_resize function called */
|
||||
#define KS_POOL_FUNC_INCREF 7 /* reference count incremented */
|
||||
#define KS_POOL_FUNC_DECREF 8 /* reference count decremented */
|
||||
|
||||
/*
|
||||
* void ks_pool_log_func_t
|
||||
|
@ -293,6 +295,34 @@ KS_DECLARE(void *) ks_pool_calloc_ex(ks_pool_t *mp_p, const unsigned long ele_n,
|
|||
|
||||
KS_DECLARE(ks_status_t) ks_pool_free_ex(ks_pool_t *mp_p, void **addrP);
|
||||
|
||||
|
||||
/*
|
||||
* void *ks_pool_ref_ex
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* Ref count increment an address in a memoory pool.
|
||||
*
|
||||
* RETURNS:
|
||||
*
|
||||
* Success - The same pointer
|
||||
*
|
||||
* Failure - NULL
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* mp_p <-> Pointer to the memory pool.
|
||||
*
|
||||
* addr -> The addr to ref
|
||||
*
|
||||
* error_p <- Pointer to integer which, if not NULL, will be set with
|
||||
* a ks_pool error code.
|
||||
*/
|
||||
|
||||
KS_DECLARE(void *) ks_pool_ref_ex(ks_pool_t *mp_p, void *addr, ks_status_t *error_p);
|
||||
|
||||
#define ks_pool_ref(_p, _x) ks_pool_ref_ex(_p, _x, NULL)
|
||||
|
||||
/*
|
||||
* void *ks_pool_resize
|
||||
*
|
||||
|
|
|
@ -85,6 +85,7 @@ KS_BEGIN_EXTERN_C
|
|||
KS_STATUS_INACTIVE,
|
||||
KS_STATUS_TIMEOUT,
|
||||
/* Memory pool errors */
|
||||
KS_STATUS_REFS_EXIST, /* references exist */
|
||||
KS_STATUS_ARG_NULL, /* function argument is null */
|
||||
KS_STATUS_ARG_INVALID, /* function argument is invalid */
|
||||
KS_STATUS_PNT, /* invalid ks_pool pointer */
|
||||
|
@ -105,6 +106,7 @@ KS_BEGIN_EXTERN_C
|
|||
KS_STATUS_ALLOC, /* calloc,malloc,free,realloc failed */
|
||||
KS_STATUS_PNT_OVER, /* pointer structure was overwritten */
|
||||
KS_STATUS_INVALID_POINTER, /* address is not valid */
|
||||
KS_STATUS_NOT_ALLOWED, /* operation is not allowed */
|
||||
/* Always insert new entries above this line*/
|
||||
KS_STATUS_COUNT
|
||||
} ks_status_t;
|
||||
|
|
|
@ -52,6 +52,7 @@ typedef struct alloc_prefix_s {
|
|||
unsigned char m1;
|
||||
unsigned long size;
|
||||
unsigned char m2;
|
||||
unsigned int refs;
|
||||
} alloc_prefix_t;
|
||||
|
||||
#define PREFIX_SIZE sizeof(struct alloc_prefix_s)
|
||||
|
@ -949,6 +950,12 @@ static void *alloc_mem(ks_pool_t *mp_p, const unsigned long byte_size, ks_status
|
|||
prefix->m1 = PRE_MAGIC1;
|
||||
prefix->m2 = PRE_MAGIC2;
|
||||
prefix->size = size;
|
||||
prefix->refs++;
|
||||
|
||||
if (mp_p->mp_log_func != NULL) {
|
||||
alloc_prefix_t *prefix = (alloc_prefix_t *) ((char *) addr - PREFIX_SIZE);
|
||||
mp_p->mp_log_func(mp_p, KS_POOL_FUNC_INCREF, prefix->size, prefix->refs, NULL, addr, 0);
|
||||
}
|
||||
|
||||
/* maintain our stats */
|
||||
mp_p->mp_alloc_c++;
|
||||
|
@ -995,6 +1002,14 @@ static int free_mem(ks_pool_t *mp_p, void *addr)
|
|||
return KS_STATUS_INVALID_POINTER;
|
||||
}
|
||||
|
||||
if (prefix->refs > 0) {
|
||||
prefix->refs--;
|
||||
}
|
||||
|
||||
if (prefix->refs > 0) {
|
||||
return KS_STATUS_REFS_EXIST;
|
||||
}
|
||||
|
||||
size = prefix->size;
|
||||
|
||||
/*
|
||||
|
@ -1645,7 +1660,11 @@ KS_DECLARE(ks_status_t) ks_pool_free_ex(ks_pool_t *mp_p, void **addrP)
|
|||
|
||||
if (mp_p->mp_log_func != NULL) {
|
||||
alloc_prefix_t *prefix = (alloc_prefix_t *) ((char *) addr - PREFIX_SIZE);
|
||||
mp_p->mp_log_func(mp_p, KS_POOL_FUNC_FREE, prefix->size, 0, NULL, addr, 0);
|
||||
if (prefix->refs == 1) {
|
||||
mp_p->mp_log_func(mp_p, KS_POOL_FUNC_FREE, prefix->size, prefix->refs - 1, NULL, addr, 0);
|
||||
} else {
|
||||
mp_p->mp_log_func(mp_p, KS_POOL_FUNC_DECREF, prefix->size, prefix->refs - 1, NULL, addr, 0);
|
||||
}
|
||||
}
|
||||
|
||||
r = free_mem(mp_p, addr);
|
||||
|
@ -1662,13 +1681,68 @@ KS_DECLARE(ks_status_t) ks_pool_free_ex(ks_pool_t *mp_p, void **addrP)
|
|||
|
||||
}
|
||||
|
||||
/*
|
||||
* void *ks_pool_ref_ex
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* Ref count increment an address in a memoory pool.
|
||||
*
|
||||
* RETURNS:
|
||||
*
|
||||
* Success - The same pointer
|
||||
*
|
||||
* Failure - NULL
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* mp_p <-> Pointer to the memory pool.
|
||||
*
|
||||
* addr -> The addr to ref
|
||||
*
|
||||
* error_p <- Pointer to integer which, if not NULL, will be set with
|
||||
* a ks_pool error code.
|
||||
*/
|
||||
KS_DECLARE(void *) ks_pool_ref_ex(ks_pool_t *mp_p, void *addr, ks_status_t *error_p)
|
||||
{
|
||||
alloc_prefix_t *prefix;
|
||||
|
||||
if (mp_p->mp_magic != KS_POOL_MAGIC) {
|
||||
SET_POINTER(error_p, KS_STATUS_PNT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (mp_p->mp_magic2 != KS_POOL_MAGIC) {
|
||||
SET_POINTER(error_p, KS_STATUS_POOL_OVER);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ks_mutex_lock(mp_p->mutex);
|
||||
prefix = (alloc_prefix_t *) ((char *) addr - PREFIX_SIZE);
|
||||
|
||||
if (!(prefix->m1 == PRE_MAGIC1 && prefix->m2 == PRE_MAGIC2)) {
|
||||
SET_POINTER(error_p, KS_STATUS_INVALID_POINTER);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
prefix->refs++;
|
||||
|
||||
if (mp_p->mp_log_func != NULL) {
|
||||
alloc_prefix_t *prefix = (alloc_prefix_t *) ((char *) addr - PREFIX_SIZE);
|
||||
mp_p->mp_log_func(mp_p, KS_POOL_FUNC_INCREF, prefix->size, prefix->refs, NULL, addr, 0);
|
||||
}
|
||||
|
||||
ks_mutex_unlock(mp_p->mutex);
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
/*
|
||||
* void *ks_pool_resize_ex
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* Reallocate an address in a mmeory pool to a new size. This is
|
||||
* different from realloc in that it needs the old address' size.
|
||||
* Reallocate an address in a memory pool to a new size. This is
|
||||
*
|
||||
* RETURNS:
|
||||
*
|
||||
|
@ -1722,6 +1796,12 @@ KS_DECLARE(void *) ks_pool_resize_ex(ks_pool_t *mp_p, void *old_addr, const unsi
|
|||
|
||||
|
||||
ks_mutex_lock(mp_p->mutex);
|
||||
|
||||
if (prefix->refs > 1) {
|
||||
SET_POINTER(error_p,KS_STATUS_NOT_ALLOWED);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
old_byte_size = prefix->size;
|
||||
|
||||
/*
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "tap.h"
|
||||
#define STR "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
|
||||
static void fill(char *str, int bytes, char c)
|
||||
{
|
||||
|
@ -48,7 +49,7 @@ int main(int argc, char **argv)
|
|||
|
||||
ks_init();
|
||||
|
||||
plan(11);
|
||||
plan(14);
|
||||
|
||||
if (argc > 1) {
|
||||
int tmp = atoi(argv[1]);
|
||||
|
@ -100,10 +101,38 @@ int main(int argc, char **argv)
|
|||
exit(255);
|
||||
}
|
||||
|
||||
fill(str, bytes, '-');
|
||||
|
||||
ks_snprintf(str, bytes, "%s", STR);
|
||||
printf("%s\n", str);
|
||||
|
||||
|
||||
printf("ALLOC3 (refs):\n");
|
||||
|
||||
str = ks_pool_ref(pool, str);
|
||||
|
||||
printf("STR [%s]\n", str);
|
||||
|
||||
ks_pool_free(pool, &str);
|
||||
|
||||
ok(str != NULL && !strcmp(str, STR));
|
||||
|
||||
printf("STR [%s]\n", str);
|
||||
|
||||
ks_pool_free(pool, &str);
|
||||
|
||||
ok(str == NULL);
|
||||
|
||||
str = ks_pool_alloc(pool, bytes);
|
||||
|
||||
ok(str != NULL);
|
||||
if (!str) {
|
||||
fprintf(stderr, "ALLOC2 ERR: [FAILED]\n");
|
||||
exit(255);
|
||||
}
|
||||
|
||||
fill(str, bytes, '-');
|
||||
printf("%s\n", str);
|
||||
|
||||
printf("ALLOC OBJ:\n");
|
||||
|
||||
foo = ks_pool_alloc(pool, sizeof(struct foo));
|
||||
|
@ -168,13 +197,13 @@ int main(int argc, char **argv)
|
|||
printf("RESIZE:\n");
|
||||
|
||||
|
||||
ks_snprintf(str, bytes, "%s", "ABCDEFGHIJKLM");
|
||||
ks_snprintf(str, bytes, "%s", STR);
|
||||
printf("1 STR [%s]\n", str);
|
||||
bytes *= 2;
|
||||
str = ks_pool_resize(pool, str, bytes);
|
||||
printf("2 STR [%s]\n", str);
|
||||
|
||||
ok(!strcmp(str, "ABCDEFGHIJKLM"));
|
||||
ok(!strcmp(str, STR));
|
||||
|
||||
if (!str) {
|
||||
fprintf(stderr, "RESIZE ERR: [FAILED]\n");
|
||||
|
|
Loading…
Reference in New Issue