Changeset: 018a7578b203 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/018a7578b203
Modified Files:
gdk/gdk.h
gdk/gdk_utils.c
monetdb5/mal/mal_dataflow.c
monetdb5/modules/mal/groupby.c
monetdb5/modules/mal/manifold.c
Branch: resource_management
Log Message:
conditional lock for allocator
diffs (truncated from 307 to 300 lines):
diff --git a/gdk/gdk.h b/gdk/gdk.h
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -2540,7 +2540,7 @@ typedef struct allocator {
bool tmp_active; /* currently only one level of temp usage */
exception_buffer eb;
MT_Lock lock; /* lock for thread-safe allocations */
- bool locked;
+ bool use_lock;
} allocator;
gdk_export ValPtr VALcopy(allocator *va, ValPtr dst, const ValRecord *src)
@@ -2548,7 +2548,7 @@ gdk_export ValPtr VALcopy(allocator *va,
gdk_export ValPtr VALinit(allocator *va, ValPtr d, int tpe, const void *s)
__attribute__((__access__(write_only, 1)));
-gdk_export allocator *create_allocator( allocator *pa);
+gdk_export allocator *create_allocator( allocator *pa, bool use_lock);
gdk_export allocator *sa_reset( allocator *sa );
gdk_export void *sa_alloc( allocator *sa, size_t sz );
gdk_export void *sa_zalloc( allocator *sa, size_t sz );
@@ -2562,8 +2562,8 @@ gdk_export void sa_open( allocator *sa )
gdk_export void sa_close( allocator *sa ); /* close temporary frame, reset to
old state */
gdk_export void sa_free( allocator *sa, void *);
-#define sa_create(pa) create_allocator(pa)
-#define ma_create(pa) sa_create(pa)
+#define sa_create(pa) create_allocator(pa, false)
+#define ma_create(pa) create_allocator(pa, true)
#define ma_destroy(ma) sa_destroy(ma)
#define ma_alloc(ma, sz) (void*)sa_alloc(ma, sz)
#define ma_zalloc(ma, sz) (void*)sa_zalloc(ma, sz)
diff --git a/gdk/gdk_utils.c b/gdk/gdk_utils.c
--- a/gdk/gdk_utils.c
+++ b/gdk/gdk_utils.c
@@ -2092,6 +2092,19 @@ eb_error(exception_buffer *eb, const cha
#define round16(sz) ((sz+15)&~15)
#define round_block_size(sz) ((sz + (SA_BLOCK_SIZE - 1))&~(SA_BLOCK_SIZE - 1))
+#define COND_LOCK_ALLOCATOR(a) \
+ bool __alloc_locked = false; \
+ if ((a)->pa == NULL && a->use_lock) { \
+ MT_lock_set(&(a)->lock); \
+ __alloc_locked = true; \
+ }
+
+#define COND_UNLOCK_ALLOCATOR(a) \
+ if (__alloc_locked) { \
+ MT_lock_unset(&(a)->lock); \
+ }
+
+
typedef struct freed_t {
size_t sz;
struct freed_t *n;
@@ -2113,13 +2126,14 @@ sa_free_obj(allocator *sa, void *obj, si
// break;
//}
//assert (i < pa->nr);
- // put on the freelist
+ COND_LOCK_ALLOCATOR(sa);
freed_t *f = obj;
f->sz = sz;
f->n = sa->freelist;
sa->freelist = f;
if (sa->inuse > 0)
sa->inuse -= 1;
+ COND_UNLOCK_ALLOCATOR(sa);
}
@@ -2134,6 +2148,7 @@ sa_free_blk(allocator *sa, void *blk)
if (sa->pa) {
sa_free_blk(sa->pa, blk);
} else {
+ COND_LOCK_ALLOCATOR(sa);
size_t i;
for(i = 0; i < sa->nr; i++) {
@@ -2157,6 +2172,7 @@ sa_free_blk(allocator *sa, void *blk)
sa->blks[i] = sa->blks[i+1];
sa->nr--;
}
+ COND_UNLOCK_ALLOCATOR(sa);
}
}
@@ -2165,21 +2181,23 @@ sa_free_blk(allocator *sa, void *blk)
* Return first slot that will fit the size
*/
static void *
-sa_use_freed_obj(allocator *pa, size_t sz)
+sa_use_freed_obj(allocator *sa, size_t sz)
{
freed_t *prev = NULL;
- freed_t *curr = pa->freelist;
+ int cntr = 0;
int MAX_ITERATIONS = 100;
- int cntr = 0;
+ COND_LOCK_ALLOCATOR(sa);
+ freed_t *curr = sa->freelist;
while(curr && (cntr < MAX_ITERATIONS)) {
if (sz <= curr->sz) {
if (prev) {
prev->n = curr->n;
} else {
- pa->freelist = curr->n;
+ sa->freelist = curr->n;
}
- pa->free_obj_hits += 1;
- pa->inuse += 1;
+ sa->free_obj_hits += 1;
+ sa->inuse += 1;
+ COND_UNLOCK_ALLOCATOR(sa);
return curr;
} else {
prev = curr;
@@ -2187,6 +2205,7 @@ sa_use_freed_obj(allocator *pa, size_t s
}
cntr += 1;
}
+ COND_UNLOCK_ALLOCATOR(sa);
return NULL;
}
@@ -2194,16 +2213,19 @@ sa_use_freed_obj(allocator *pa, size_t s
* Free blocks are maintain at top level
*/
static void *
-sa_use_freed_blk(allocator *pa, size_t sz)
+sa_use_freed_blk(allocator *sa, size_t sz)
{
- if (pa->pa)
- return sa_use_freed_blk(pa->pa, sz);
- if (pa->freelist_blks && (sz == SA_BLOCK_SIZE)) {
- freed_t *f = pa->freelist_blks;
- pa->freelist_blks = f->n;
- pa->free_blk_hits += 1;
+ if (sa->pa)
+ return sa_use_freed_blk(sa->pa, sz);
+ COND_LOCK_ALLOCATOR(sa);
+ if (sa->freelist_blks && (sz == SA_BLOCK_SIZE)) {
+ freed_t *f = sa->freelist_blks;
+ sa->freelist_blks = f->n;
+ sa->free_blk_hits += 1;
+ MT_lock_unset(&sa->lock);
return f;
}
+ COND_UNLOCK_ALLOCATOR(sa);
return NULL;
}
@@ -2211,7 +2233,7 @@ sa_use_freed_blk(allocator *pa, size_t s
static void *
sa_use_freed(allocator *sa, size_t sz)
{
- if ((sz < SA_BLOCK_SIZE) && sa->freelist) {
+ if (sz < SA_BLOCK_SIZE) {
return sa_use_freed_obj(sa, sz);
}
if (sz == SA_BLOCK_SIZE) {
@@ -2222,15 +2244,19 @@ sa_use_freed(allocator *sa, size_t sz)
/*
- * Reset allocator to initial state
+ * Reset child allocator to initial state
* free all but 1st blk
*/
allocator *sa_reset(allocator *sa)
{
size_t i;
+ size_t n_blks = sa->nr;
+ char **blks = sa->blks;
- for (i = 1; i < sa->nr; i++) {
- char *next = sa->blks[i];
+ assert(sa->pa);
+
+ for (i = 1; i < n_blks; i++) {
+ char *next = blks[i];
sa_free_blk(sa, next);
//if (sa->pa == NULL) {
// GDKfree(next);
@@ -2284,6 +2310,7 @@ static void *
char *r = sa_use_freed(sa, sz);
if (r)
return r;
+ COND_LOCK_ALLOCATOR(sa);
if (sz > (sa->blk_size - sa->used)) {
// out of space need new blk
size_t nsize = SA_BLOCK_SIZE;
@@ -2299,6 +2326,7 @@ static void *
if (r == NULL) {
if (sa->eb.enabled)
eb_error(&sa->eb, "out of memory", 1000);
+ COND_UNLOCK_ALLOCATOR(sa);
return NULL;
}
if (sa->nr >= sa->size) {
@@ -2311,6 +2339,7 @@ static void *
tmp = GDKrealloc(sa->blks, sizeof(char*) *
sa->size);
if (tmp == NULL) {
sa->size /= 2; /* undo */
+ COND_UNLOCK_ALLOCATOR(sa);
if (sa->eb.enabled)
eb_error(&sa->eb, "out of memory",
1000);
if (!sa->pa)
@@ -2330,6 +2359,7 @@ static void *
}
sa->objects += 1;
sa->inuse += 1;
+ COND_UNLOCK_ALLOCATOR(sa);
return r;
}
@@ -2351,7 +2381,7 @@ sa_alloc(allocator *sa, size_t sz)
allocator *
-create_allocator(allocator *pa)
+create_allocator(allocator *pa, bool use_lock)
{
// ask blk first so subsequent allocations are
// within that blk if there is pa
@@ -2389,8 +2419,8 @@ create_allocator(allocator *pa)
sa->free_blk_hits = 0;
sa->tmp_active = 0;
sa->tmp_used = 0;
+ sa->use_lock = use_lock;
MT_lock_init(&sa->lock, "allocator_lock");
- sa->locked = false;
return sa;
}
@@ -2409,7 +2439,6 @@ void
sa_destroy(allocator *sa)
{
if (sa) {
- MT_lock_destroy(&sa->lock);
bool root_allocator = sa->pa == NULL;
for (size_t i = 0; i < sa->nr; i++) {
char *next = sa->blks[i];
@@ -2420,6 +2449,7 @@ sa_destroy(allocator *sa)
}
sa->blks[i] = NULL;
}
+ MT_lock_destroy(&sa->lock);
if (root_allocator) {
GDKfree(sa->blks);
GDKfree(sa);
diff --git a/monetdb5/mal/mal_dataflow.c b/monetdb5/mal/mal_dataflow.c
--- a/monetdb5/mal/mal_dataflow.c
+++ b/monetdb5/mal/mal_dataflow.c
@@ -336,16 +336,11 @@ DFLOWworker(void *T)
break;
}
- allocator *pa = flow->cntxt->alloc;
- MT_lock_set(&pa->lock);
- // TODO perhaps use tiny size allocator!
+ allocator *pa = flow->mb->ma;
allocator *ta = ma_create(pa);
- MT_lock_unset(&pa->lock);
error = runMALsequence(ta, flow->cntxt, flow->mb,
fe->pc, fe->pc + 1,
flow->stk,
0, 0);
- MT_lock_set(&pa->lock);
ma_destroy(ta);
- MT_lock_unset(&pa->lock);
ATOMIC_DEC(&flow->cntxt->workers);
/* release the memory claim */
diff --git a/monetdb5/modules/mal/groupby.c b/monetdb5/modules/mal/groupby.c
--- a/monetdb5/modules/mal/groupby.c
+++ b/monetdb5/modules/mal/groupby.c
@@ -75,10 +75,8 @@ GROUPcollect(Client cntxt, MalBlkPtr mb,
(void) mb;
(void) cntxt;
allocator *ma = mb->ma;
- MT_lock_set(&ma->lock);
a = (AGGRtask *) ma_alloc(ma, sizeof(*a));
if (a == NULL) {
- MT_lock_unset(&ma->lock);
return NULL;
}
*a = (AGGRtask) {
@@ -86,7 +84,6 @@ GROUPcollect(Client cntxt, MalBlkPtr mb,
.cols = ma_zalloc(ma, pci->argc * sizeof(BAT *)),
.unique = ma_zalloc(ma, pci->argc * sizeof(BUN)),
};
- MT_lock_unset(&ma->lock);
if (a->cols == NULL || a->bid == NULL || a->unique == NULL) {
//GDKfree(a->cols);
//GDKfree(a->bid);
diff --git a/monetdb5/modules/mal/manifold.c b/monetdb5/modules/mal/manifold.c
--- a/monetdb5/modules/mal/manifold.c
+++ b/monetdb5/modules/mal/manifold.c
@@ -320,9 +320,7 @@ MANIFOLDevaluate(Client cntxt, MalBlkPtr
throw(MAL, "mal.manifold", "Illegal manifold function call");
}
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]