#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
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
*
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 */
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;
unsigned char m1;
unsigned long size;
unsigned char m2;
+ unsigned int refs;
} alloc_prefix_t;
#define PREFIX_SIZE sizeof(struct alloc_prefix_s)
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++;
return KS_STATUS_INVALID_POINTER;
}
+ if (prefix->refs > 0) {
+ prefix->refs--;
+ }
+
+ if (prefix->refs > 0) {
+ return KS_STATUS_REFS_EXIST;
+ }
+
size = prefix->size;
/*
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);
}
+/*
+ * 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:
*
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;
/*
#include <stdio.h>
#include <string.h>
#include "tap.h"
+#define STR "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
static void fill(char *str, int bytes, char c)
{
ks_init();
- plan(11);
+ plan(14);
if (argc > 1) {
int tmp = atoi(argv[1]);
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));
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");