Switched to growable (unlimited) persistent objects / static references

repositories. Has been tested with 15K objects and appears to work. Also
done some significant chnages to auxiliary modules in libpobj, and the
trivial test program (test-list).
This commit is contained in:
Gilad Arnold 2004-12-16 09:00:07 +00:00
parent e30aca6138
commit 6502569a02
7 changed files with 754 additions and 562 deletions

View file

@ -4,7 +4,7 @@
#include <stdio.h>
/* FIXME: send that to the make system. */
#define HAVE_DEBUG
/* #define HAVE_DEBUG */
#ifdef HAVE_DEBUG
#define debug(format,...) \

View file

@ -4,49 +4,72 @@
#include "xmem.h"
/* Hash item. */
struct hash_item {
struct hash_item *next;
unsigned long key;
unsigned long val;
};
struct hash_table {
int bucket_max;
unsigned long bucket_mask;
struct hash_item **table;
};
void
hash_init (hash_table table, int nbuckexp)
struct hash_table *
hash_new (int nbuckexp)
{
int bucket_max = (int) ((unsigned long) 1 << nbuckexp);
unsigned long bucket_mask = (unsigned long) bucket_max - 1;
struct hash_table *h;
memset (table, 0, bucket_max * sizeof (struct hash_item *));
h = (struct hash_table *) XMALLOC (sizeof (struct hash_table));
if (h)
h->table =
(struct hash_item **) XMALLOC (sizeof (struct hash_item *) * bucket_max);
if (! (h && h->table)) {
if (h)
XFREE (h);
return NULL;
}
h->bucket_max = bucket_max;
h->bucket_mask = bucket_mask;
memset (h->table, 0, sizeof (struct hash_item *) * bucket_max);
return h;
}
void
hash_close (hash_table table, int nbuckexp)
hash_free (struct hash_table *h)
{
int bucket_max = (int) ((unsigned long) 1 << nbuckexp);
int bucket_max = h->bucket_max;
struct hash_item *bucket, *next;
int i;
for (i = 0; i < bucket_max; i++) {
for (bucket = table[i]; bucket; bucket = next) {
for (bucket = h->table[i]; bucket; bucket = next) {
next = bucket->next;
XFREE (XMEM_HASH, bucket);
XFREE (bucket);
}
table[i] = NULL;
}
XFREE (h->table);
XFREE (h);
}
unsigned long
hash_lookup (hash_table table, int nbuckexp, unsigned long key)
hash_lookup (struct hash_table *h, unsigned long key)
{
int bucket_index = (int) (key & (((unsigned long) 1 << nbuckexp) - 1));
unsigned long bucket_mask = h->bucket_mask;
int bucket_index = (int) (key & bucket_mask);
struct hash_item *bucket;
unsigned long val;
debug ("tracing bucket %d for key %lu (%p)",
bucket_index, key, (void *) key);
for (bucket = table[bucket_index]; bucket; bucket = bucket->next)
for (bucket = h->table[bucket_index]; bucket; bucket = bucket->next)
if (bucket->key == key) {
val = bucket->val;
debug ("found %lu->%lu (%p->%p)",
@ -60,33 +83,34 @@ hash_lookup (hash_table table, int nbuckexp, unsigned long key)
}
void
hash_insert (hash_table table, int nbuckexp,
unsigned long key, unsigned long val)
hash_insert (struct hash_table *h, unsigned long key, unsigned long val)
{
int bucket_index = (int) (key & (((unsigned long) 1 << nbuckexp) - 1));
unsigned long bucket_mask = h->bucket_mask;
int bucket_index = (int) (key & bucket_mask);
struct hash_item *new;
debug ("inserting %lu->%lu (%p->%p) to bucket %d",
key, val, (void *) key, (void *) val, bucket_index);
new = (struct hash_item *) XMALLOC (XMEM_HASH, sizeof (struct hash_item));
new = (struct hash_item *) XMALLOC (sizeof (struct hash_item));
new->key = key;
new->val = val;
new->next = table[bucket_index];
table[bucket_index] = new;
new->next = h->table[bucket_index];
h->table[bucket_index] = new;
}
unsigned long
hash_delete (hash_table table, int nbuckexp, unsigned long key)
hash_delete (struct hash_table *h, unsigned long key)
{
int bucket_index = (int) (key & (((unsigned long) 1 << nbuckexp) - 1));
unsigned long bucket_mask = h->bucket_mask;
int bucket_index = (int) (key & bucket_mask);
struct hash_item *bucket, *prev;
unsigned long val;
debug ("tracing bucket %d for key %lu (%p)",
bucket_index, key, (void *) key);
for (prev = NULL, bucket = table[bucket_index]; bucket;
for (prev = NULL, bucket = h->table[bucket_index]; bucket;
prev = bucket, bucket = bucket->next)
if (bucket->key == key) {
val = bucket->val;
@ -96,9 +120,9 @@ hash_delete (hash_table table, int nbuckexp, unsigned long key)
if (prev)
prev->next = bucket->next;
else
table[bucket_index] = bucket->next;
h->table[bucket_index] = bucket->next;
XFREE (XMEM_HASH, bucket);
XFREE (bucket);
return val;
}

View file

@ -1,18 +1,13 @@
#ifndef __HASH_H
#define __HASH_H
struct hash_table;
/* Hash table type and declaration macro. */
typedef struct hash_item **hash_table;
#define HASH_DECLARE(name,nbuckexp) struct hash_item *name[1 << nbuckexp]
/* Prototypes. */
void hash_init (hash_table, int);
void hash_close (hash_table, int);
unsigned long hash_lookup (hash_table, int, unsigned long);
void hash_insert (hash_table, int, unsigned long, unsigned long);
unsigned long hash_delete (hash_table, int, unsigned long);
struct hash_table *hash_new (int);
void hash_free (struct hash_table *);
unsigned long hash_lookup (struct hash_table *, unsigned long);
void hash_insert (struct hash_table *, unsigned long, unsigned long);
unsigned long hash_delete (struct hash_table *, unsigned long);
#endif /* __HASH_H */

File diff suppressed because it is too large Load diff

View file

@ -1,117 +1,79 @@
#include <stdlib.h>
#include "common.h"
#include "xmem.h"
struct xmem {
#define member_sizeof(s,x) (sizeof(((s *)NULL)->x))
#define member_offset(s,x) ((int)&(((s *)NULL)->x))
#ifdef HAVE_XMEM_DETAIL
/* Extended memory block info. */
int mtype;
struct xmem {
char *file;
int line;
int size;
struct xmem *prev;
struct xmem *next;
#endif /* HAVE_XMEM_DETAIL */
/* Dummy field used to infer alignment. */
int dummy;
int dummy; /* dummy field to infer alignment. */
};
#define XMEM_OFFSET member_offset (struct xmem, dummy)
#ifdef HAVE_XMEM
struct xmem_stat {
unsigned long count;
#ifdef HAVE_XMEM_DETAIL
unsigned long size;
struct xmem *head;
struct xmem *tail;
# define XMEM_OFFSET member_offset (struct xmem, dummy)
#endif /* HAVE_XMEM_DETAIL */
} xmem_stats[XMEM_MAX] = { { 0 } };
#endif /* HAVE_XMEM */
/* Default memory calls. */
void *(*g_memfunc_malloc) (size_t) = malloc;
void *(*g_memfunc_realloc) (void *, size_t) = realloc;
void (*g_memfunc_free) (void *) = free;
#ifdef HAVE_XMEM_DETAIL
void *
xmem_malloc (int mtype, char *file, int line, size_t size)
xmem_malloc (char *file, int line, size_t size)
{
struct xmem *x;
x = (struct xmem *) g_memfunc_malloc (size + XMEM_OFFSET);
if (! x)
exit (1);
return NULL;
x->file = file;
x->line = line;
x->size = size;
return (void *) ((char *) x + XMEM_OFFSET);
}
void *
xmem_realloc (char *file, int line, void *p, size_t size)
{
struct xmem *x = (struct xmem *) ((char *) p - XMEM_OFFSET);
x = (struct xmem *) g_memfunc_realloc (x, size + XMEM_OFFSET);
if (! x)
return NULL;
#ifdef HAVE_XMEM_DETAIL
/* Update object's extended info. */
x->mtype = mtype;
x->file = file;
x->line = line;
x->size = size;
/* Attach to object type list. */
x->next = NULL;
x->prev = xmem_stats[mtype].tail;
if (xmem_stats[mtype].tail)
xmem_stats[mtype].tail->next = x;
xmem_stats[mtype].tail = x;
if (! xmem_stats[mtype].head)
xmem_stats[mtype].head = x;
/* Update accumulated object sizes. */
xmem_stats[mtype].size += (unsigned long) size;
#endif /* HAVE_XMEM_DETAIL */
#ifdef HAVE_XMEM
/* Update accumulated type counter. */
xmem_stats[mtype].count++;
#endif /* HAVE_XMEM */
return (void *) (((char *) x) + XMEM_OFFSET);
return (void *) ((char *) x + XMEM_OFFSET);
}
void
xmem_free (int mtype, void *p)
xmem_free (void *p)
{
struct xmem *x = (struct xmem *) (((char *) p) - XMEM_OFFSET);
#ifdef HAVE_XMEM_DETAIL
/* Verify object type consistency. */
if (mtype == XMEM_MAX)
mtype = x->mtype;
else if (mtype != x->mtype)
exit (1);
/* Detach from type list. */
if (x->prev)
x->prev->next = x->next;
else
xmem_stats[mtype].head = x->next;
if (x->next)
x->next->prev = x->prev;
else
xmem_stats[mtype].tail = x->prev;
/* Update accumulated object sizes. */
xmem_stats[mtype].size -= (unsigned long) x->size;
#endif /* HAVE_XMEM_DETAIL */
#ifdef HAVE_XMEM
/* Update accumulated type counter. */
xmem_stats[mtype].count--;
#endif /* HAVE_XMEM */
struct xmem *x = (struct xmem *) ((char *) p - XMEM_OFFSET);
g_memfunc_free (x);
}
#endif /* HAVE_XMEM_DETAIL */
int
xmem_memfunc (void *(*memfunc_malloc)(size_t), void (*memfunc_free)(void *))
xmem_memfunc (void *(*memfunc_malloc) (size_t),
void *(*memfunc_realloc) (void *, size_t),
void (*memfunc_free) (void *))
{
if (memfunc_malloc)
g_memfunc_malloc = memfunc_malloc;
if (memfunc_realloc)
g_memfunc_realloc = memfunc_realloc;
if (memfunc_free)
g_memfunc_free = memfunc_free;
@ -119,22 +81,11 @@ xmem_memfunc (void *(*memfunc_malloc)(size_t), void (*memfunc_free)(void *))
}
int
xmem_obj_mtype (void *p)
{
#ifdef HAVE_XMEM_DETAIL
struct xmem *x = (struct xmem *) (((char *) p) - XMEM_OFFSET);
return x->mtype;
#else
return 0;
#endif /* HAVE_XMEM_DETAIL */
}
char *
xmem_obj_file (void *p)
xmem_get_file (void *p)
{
#ifdef HAVE_XMEM_DETAIL
struct xmem *x = (struct xmem *) (((char *) p) - XMEM_OFFSET);
struct xmem *x = (struct xmem *) ((char *) p - XMEM_OFFSET);
return x->file;
#else
return NULL;
@ -142,10 +93,10 @@ xmem_obj_file (void *p)
}
int
xmem_obj_line (void *p)
xmem_get_line (void *p)
{
#ifdef HAVE_XMEM_DETAIL
struct xmem *x = (struct xmem *) (((char *) p) - XMEM_OFFSET);
struct xmem *x = (struct xmem *) ((char *) p - XMEM_OFFSET);
return x->line;
#else
return 0;
@ -153,49 +104,12 @@ xmem_obj_line (void *p)
}
size_t
xmem_obj_size (void *p)
xmem_get_size (void *p)
{
#ifdef HAVE_XMEM_DETAIL
struct xmem *x = (struct xmem *) (((char *) p) - XMEM_OFFSET);
struct xmem *x = (struct xmem *) ((char *) p - XMEM_OFFSET);
return x->size;
#else
return 0;
#endif /* HAVE_XMEM_DETAIL */
}
unsigned long
xmem_stat_count (int mtype)
{
#ifdef HAVE_XMEM
return xmem_stats[mtype].count;
#else
return 0;
#endif /* HAVE_XMEM */
}
unsigned long
xmem_stat_size (int mtype)
{
#ifdef HAVE_XMEM_DETAIL
return xmem_stats[mtype].size;
#else
return 0;
#endif /* HAVE_XMEM_DETAIL */
}
unsigned long
xmem_stat_alloc_list (int mtype, void (*cb) (char *, int, size_t, void *))
{
unsigned long count = 0;
#ifdef HAVE_XMEM_DETAIL
struct xmem *x = xmem_stats[mtype].head;
while (x) {
cb (x->file, x->line, x->size, ((char *) x) + XMEM_OFFSET);
count++;
x = x->next;
}
#endif /* HAVE_XMEM_DETAIL */
return count;
}

View file

@ -1,35 +1,26 @@
#ifndef __XMEM_H
#define __XMEM_H
enum {
/* General purpose identifiers. */
XMEM_TMP = 0,
XMEM_STR,
/* Dedicated object identifiers. */
XMEM_POBJ,
XMEM_HASH,
/* Teminator (don't use). */
XMEM_MAX
};
#define XMALLOC(t,s) xmem_malloc (t, __FILE__, __LINE__, s)
#define XFREE(t,p) xmem_free (t, p)
#ifdef HAVE_XMEM_DETAIL
#define XFREE_ANY(p) xmem_free (XMEM_MAX, p)
void *xmem_malloc (char *, int, size_t);
void *xmem_realloc (char *, int, void *, size_t);
void xmem_free (void *);
# define XMALLOC(s) xmem_malloc (__FILE__, __LINE__, s)
# define XREALLOC(p,s) xmem_malloc (__FILE__, __LINE__, p, s)
# define XFREE(p) xmem_free (p)
#else
extern void *(*g_memfunc_malloc) (size_t);
extern void *(*g_memfunc_realloc) (void *, size_t);
extern void (*g_memfunc_free) (void *);
# define XMALLOC(s) g_memfunc_malloc(s)
# define XREALLOC(p,s) g_memfunc_realloc(p,s)
# define XFREE(p) g_memfunc_free(p)
#endif /* HAVE_XMEM_DETAIL */
void *xmem_malloc (int, char *, int, size_t);
void xmem_free (int, void *);
int xmem_memfunc (void *(*) (size_t), void (*) (void *));
int xmem_obj_mtype (void *);
char *xmem_obj_file (void *);
int xmem_obj_line (void *);
size_t xmem_obj_size (void *);
unsigned long xmem_stat_count (int);
unsigned long xmem_stat_size (int);
unsigned long xmem_stat_alloc_list (int, void (*cb) (char *, int, size_t, void *));
int xmem_memfunc (void *(*) (size_t), void *(*) (void *, size_t), void (*) (void *));
char *xmem_get_file (void *);
int xmem_get_line (void *);
size_t xmem_get_size (void *);
#endif /* __XMEM_H */

View file

@ -25,7 +25,7 @@ main (int argc, char **argv)
printf ("first-time init\n");
/* Build list. */
next = NULL;
for (i = 0; i < 10; i++) {
for (i = 0; i < 15000; i++) {
pobj_start ();
tmp = (struct item *) pobj_malloc (sizeof (struct item));
if (! tmp) {