#include <unistd.h>
#include "portable_defns.h"
#include "gc.h"
+
+#include <afsconfig.h>
+#include <afs/param.h>
#include <afs/afsutil.h>
/*#define MINIMAL_GC*/
int nr_sizes;
int blk_sizes[MAX_SIZES];
+ /* tags (trace support) */
+ char *tags[MAX_SIZES];
+
/* Registered epoch hooks. */
int nr_hooks;
hook_fn_t hook_fns[MAX_HOOKS];
int i;
chunk_t *h, *p;
+ ViceLog(11, ("GC: alloc_more_chunks alloc %lu chunks\n",
+ CHUNKS_PER_ALLOC));
+
h = p = ALIGNED_ALLOC(CHUNKS_PER_ALLOC * sizeof(*h));
if ( h == NULL ) MEM_FAIL(CHUNKS_PER_ALLOC * sizeof(*h));
unsigned long curr_epoch;
chunk_t *ch, *t;
int two_ago, three_ago, i, j;
+
+ ViceLog(11, ("GC: gc_reclaim enter\n"));
/* Barrier to entering the reclaim critical section. */
if ( gc_global.inreclaim || CASIO(&gc_global.inreclaim, 0, 1) ) return;
+ ViceLog(11, ("GC: gc_reclaim after inreclaim barrier\n"));
+
/*
* Grab first ptst structure *before* barrier -- prevent bugs
* on weak-ordered architectures.
if ( (ptst->count > 1) && (ptst->gc->epoch != curr_epoch) ) goto out;
}
+
+ ViceLog(11, ("GC: gc_reclaim all-threads see current epoch\n"));
+
/*
* Three-epoch-old garbage lists move to allocation lists.
* Two-epoch-old garbage lists are cleaned out.
gc->garbage_tail[three_ago][i]->next = ch;
gc->garbage_tail[three_ago][i] = t;
t->next = t;
+
+ /* gc inst: compute and log size of returned list */
+ {
+ chunk_t *ch_head, *ch_next;
+ int r_ix, r_len, r_size;
+ r_ix = 0;
+ r_len = 0;
+ r_size = 0;
+
+ /* XXX: nonfatal, may be missing multiplier */
+ ch_head = ch;
+ do {
+ r_len++;
+ } while (ch->next && (ch->next != ch_head)
+ && (ch_next = ch->next));
+
+ ViceLog(11, ("GC: return %d chunks of size %d to "
+ "gc_global.alloc[%d]\n",
+ r_len,
+ gc_global.blk_sizes[i],
+ i));
+ }
+
+
add_chunks_to_list(ch, gc_global.alloc[i]);
}
do { for ( j = 0; j < t->i; j++ ) fn(our_ptst, t->blk[j]); }
while ( (t = t->next) != ch );
+ /* gc inst: compute and log size of returned list */
+ {
+ chunk_t *ch_head, *ch_next;
+ int r_ix, r_len, r_size;
+ r_ix = 0;
+ r_len = 0;
+
+ /* XXX: nonfatal, may be missing multiplier */
+ ch_head = ch;
+ do {
+ r_len++;
+ } while (ch->next && (ch->next != ch_head)
+ && (ch_next = ch->next));
+
+ ViceLog(11, ("GC: return %d chunks to gc_global.free_chunks\n",
+ r_len));
+ }
+
add_chunks_to_list(ch, gc_global.free_chunks);
}
}
/* Update current epoch. */
+ ViceLog(11, ("GC: gc_reclaim epoch transition (leaving %lu)\n",
+ curr_epoch));
+
WMB();
gc_global.current = (curr_epoch+1) % NR_EPOCHS;
return (gc_global.blk_sizes[alloc_id]);
}
+int
+gc_get_tag(int alloc_id)
+{
+ return (gc_global.tags[alloc_id]);
+}
+
static chunk_t *chunk_from_cache(gc_t *gc)
{
chunk_t *ch = gc->chunk_cache, *p = ch->next;
int
-gc_add_allocator(int alloc_size)
+gc_add_allocator(int alloc_size, char *tag)
{
int ni, i;
while ((ni = CASIO(&gc_global.nr_sizes, i, i + 1)) != i)
i = ni;
gc_global.blk_sizes[i] = alloc_size;
+ gc_global.tags[i] = strdup(tag);
gc_global.alloc_size[i] = ALLOC_CHUNKS_PER_LIST;
gc_global.alloc[i] = get_filled_chunks(ALLOC_CHUNKS_PER_LIST, alloc_size);
return i;
#include "osi_mcas_obj_cache.h"
+#include <osi/osi_includes.h>
+#include <osi/osi_types.h>
#include <afs/afsutil.h>
void
-osi_mcas_obj_cache_create(osi_mcas_obj_cache_t * gc_id, size_t size)
+osi_mcas_obj_cache_create(osi_mcas_obj_cache_t * gc_id, size_t size,
+ char *tag)
{
ViceLog(7,
("osi_mcas_obj_cache_create: size, adjsize %d\n", size,
size + sizeof(int *)));
- *(int *)gc_id = gc_add_allocator(size + sizeof(int *));
+ *(int *)gc_id = gc_add_allocator(size + sizeof(int *), tag);
}
void gc_trace(int alloc_id);
+int gc_get_tag(int alloc_id);
int gc_get_blocksize(int alloc_id);
void *
ptst_t *ptst;
void *obj;
-#if MCAS_ALLOC_DISABLED
-#warning XXXXX mcas allocator cache is DISABLED for debugging!!
- obj = malloc(gc_get_blocksize(gc_id));
-#else
ptst = critical_enter();
obj = (void *)gc_alloc(ptst, gc_id);
critical_exit(ptst);
+
+ ViceLog(11,
+ ("GC: osi_mcas_obj_cache_alloc: block of size %d "
+#if OSI_DATAMODEL_IS(OSI_ILP32_ENV)
+ "0x%lx"
+#else
+ "0x%llx"
#endif
+ " (%s)\n",
+ gc_get_blocksize(gc_id),
+ obj,
+ gc_get_tag(gc_id)));
+
return (obj);
}
{
ptst_t *ptst;
-#if MCAS_ALLOC_DISABLED
-#warning XXXXX mcas allocator cache is DISABLED for debugging!!
+ ViceLog(11,
+ ("GC: osi_mcas_obj_cache_free: block of size %d "
+#if OSI_DATAMODEL_IS(OSI_ILP32_ENV)
+ "0x%lx"
#else
+ "0x%llx"
+#endif
+ " (%s)\n",
+ gc_get_blocksize(gc_id),
+ obj,
+ gc_get_tag(gc_id)));
+
ptst = critical_enter();
gc_free(ptst, (void *)obj, gc_id);
critical_exit(ptst);
-#endif
}
void