Changeset: a1850d0d9fc4 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/a1850d0d9fc4
Modified Files:
sql/backends/monet5/sql_gencode.c
sql/include/sql_catalog.h
sql/storage/sql_storage.h
sql/storage/store.c
Branch: Jan2022
Log Message:
Use instantiation lock per function. If the locks are shared, a dealock can
occur
diffs (197 lines):
diff --git a/sql/backends/monet5/sql_gencode.c
b/sql/backends/monet5/sql_gencode.c
--- a/sql/backends/monet5/sql_gencode.c
+++ b/sql/backends/monet5/sql_gencode.c
@@ -1107,7 +1107,7 @@ backend_create_mal_func(mvc *m, sql_func
{
if (f->instantiated)
return 0;
- lock_function(m->store, f->base.id);
+ MT_lock_set(&f->function_lock);
if (!f->instantiated) {
char *F = NULL, *fn = NULL;
bit side_effect = f->side_effect;
@@ -1117,29 +1117,29 @@ backend_create_mal_func(mvc *m, sql_func
(void) F;
if (strlen(f->mod) >= IDLENGTH) {
(void) sql_error(m, 01, SQLSTATE(42000) "MAL module
name '%s' too large for the backend", f->mod);
- unlock_function(m->store, f->base.id);
+ MT_lock_unset(&f->function_lock);
return -1;
}
if (mal_function_find_implementation_address(m, f) < 0) {
- unlock_function(m->store, f->base.id);
+ MT_lock_unset(&f->function_lock);
return -1;
}
if (!backend_resolve_function(&clientid, f)) {
(void) sql_error(m, 02, SQLSTATE(3F000) "MAL external
name %s.%s not bound (%s.%s)", f->mod, f->imp, f->s->base.name, f->base.name);
_DELETE(f->imp);
- unlock_function(m->store, f->base.id);
+ MT_lock_unset(&f->function_lock);
return -1;
}
if (side_effect != f->side_effect) {
(void) sql_error(m, 02, SQLSTATE(42000) "Side-effect
value from the SQL %s %s.%s doesn't match the MAL definition %s.%s\n"
"Either re-create the
%s, or fix the MAL definition and restart the database", fn, f->s->base.name,
f->base.name, f->mod, f->imp, fn);
_DELETE(f->imp);
- unlock_function(m->store, f->base.id);
+ MT_lock_unset(&f->function_lock);
return -1;
}
f->instantiated = TRUE; /* make sure 'instantiated' gets set
after 'imp' */
}
- unlock_function(m->store, f->base.id);
+ MT_lock_unset(&f->function_lock);
return 0;
}
@@ -1153,7 +1153,7 @@ backend_create_sql_func(backend *be, sql
if (f->instantiated || (m->forward && m->forward->base.id ==
f->base.id))
return res;
- lock_function(m->store, f->base.id);
+ MT_lock_set(&f->function_lock);
if (!f->instantiated) {
MalBlkPtr curBlk = NULL;
InstrPtr curInstr = NULL;
@@ -1171,7 +1171,7 @@ backend_create_sql_func(backend *be, sql
if (r)
r = sql_processrelation(m, r, 1, 1, 0);
if (!r) {
- unlock_function(m->store, f->base.id);
+ MT_lock_unset(&f->function_lock);
return -1;
}
@@ -1179,7 +1179,7 @@ backend_create_sql_func(backend *be, sql
/* for debug builds we keep the SQL function name in the MAL
function name to make it easy to debug */
if (strlen(f->base.name) + 21 >= IDLENGTH) { /* 20 bits for u64
number + '%' */
(void) sql_error(m, 01, SQLSTATE(42000) "MAL function
name '%s' too large for the backend", f->base.name);
- unlock_function(m->store, f->base.id);
+ MT_lock_unset(&f->function_lock);
return -1;
}
(void) snprintf(befname, IDLENGTH, "%%" LLFMT "%s",
store_function_counter(m->store), f->base.name);
@@ -1334,7 +1334,7 @@ cleanup:
memcpy(be, &bebackup, sizeof(backend));
c->curprg = symbackup;
}
- unlock_function(m->store, f->base.id);
+ MT_lock_unset(&f->function_lock);
return res;
}
diff --git a/sql/include/sql_catalog.h b/sql/include/sql_catalog.h
--- a/sql/include/sql_catalog.h
+++ b/sql/include/sql_catalog.h
@@ -516,6 +516,7 @@ typedef struct sql_func {
*/
sql_schema *s;
sql_allocator *sa;
+ MT_Lock function_lock; /* protecting concurrent function
instantiations. Only used in MAL and SQL functions */
} sql_func;
typedef struct sql_subfunc {
diff --git a/sql/storage/sql_storage.h b/sql/storage/sql_storage.h
--- a/sql/storage/sql_storage.h
+++ b/sql/storage/sql_storage.h
@@ -335,8 +335,6 @@ extern lng store_hot_snapshot(struct sql
extern lng store_hot_snapshot_to_stream(struct sqlstore *store, stream *s);
extern ulng store_function_counter(struct sqlstore *store);
-extern void lock_function(struct sqlstore *store, sqlid id);
-extern void unlock_function(struct sqlstore *store, sqlid id);
extern ulng store_oldest(struct sqlstore *store);
extern ulng store_get_timestamp(struct sqlstore *store);
@@ -461,7 +459,6 @@ extern int sql_trans_copy_key(sql_trans
extern int sql_trans_copy_idx(sql_trans *tr, sql_table *t, sql_idx *i, sql_idx
**ires);
extern int sql_trans_copy_trigger(sql_trans *tr, sql_table *t, sql_trigger
*tri, sql_trigger **tres);
-#define NR_FUNCTION_LOCKS 16
#define NR_TABLE_LOCKS 64
#define NR_COLUMN_LOCKS 512
#define TRANSACTION_ID_BASE (1ULL<<63)
@@ -473,7 +470,6 @@ typedef struct sqlstore {
MT_Lock lock; /* lock protecting concurrent writes
(not reads, ie use rcu) */
MT_Lock commit; /* protect transactions, only single
commit (one wal writer) */
MT_Lock flush; /* flush lock protecting concurrent
writes (not reads, ie use rcu) */
- MT_Lock function_locks[NR_FUNCTION_LOCKS]; /* protecting
concurrent function instantiations */
MT_Lock table_locks[NR_TABLE_LOCKS]; /* protecting
concurrent writes to tables (storage) */
MT_Lock column_locks[NR_COLUMN_LOCKS]; /* protecting
concurrent writes to columns (storage) */
list *active; /* list of running transactions */
diff --git a/sql/storage/store.c b/sql/storage/store.c
--- a/sql/storage/store.c
+++ b/sql/storage/store.c
@@ -30,18 +30,6 @@ store_function_counter(sqlstore *store)
return ts;
}
-void
-lock_function(sqlstore *store, sqlid id)
-{
- MT_lock_set(&store->function_locks[id&(NR_FUNCTION_LOCKS-1)]);
-}
-
-void
-unlock_function(sqlstore *store, sqlid id)
-{
- MT_lock_unset(&store->function_locks[id&(NR_FUNCTION_LOCKS-1)]);
-}
-
static ulng
store_timestamp(sqlstore *store)
{
@@ -128,6 +116,8 @@ func_destroy(sqlstore *store, sql_func *
/* clean backend code */
backend_freecode(sql_shared_module_name, 0, f->imp);
}
+ if (f->lang == FUNC_LANG_SQL || f->lang == FUNC_LANG_MAL)
+ MT_lock_destroy(&f->function_lock);
if (f->res)
list_destroy2(f->res, store);
list_destroy2(f->ops, store);
@@ -948,6 +938,8 @@ load_func(sql_trans *tr, sql_schema *s,
t->s = s;
t->fix_scale = SCALE_EQ;
t->sa = tr->sa;
+ if (!t->instantiated)
+ MT_lock_init(&t->function_lock, "function_lock");
if (t->lang != FUNC_LANG_INT) {
t->query = t->imp;
t->imp = NULL;
@@ -2102,8 +2094,6 @@ store_init(int debug, store_type store_t
MT_lock_init(&store->lock, "sqlstore_lock");
MT_lock_init(&store->commit, "sqlstore_commit");
MT_lock_init(&store->flush, "sqlstore_flush");
- for(int i = 0; i<NR_FUNCTION_LOCKS; i++)
- MT_lock_init(&store->function_locks[i], "sqlstore_function");
for(int i = 0; i<NR_TABLE_LOCKS; i++)
MT_lock_init(&store->table_locks[i], "sqlstore_table");
for(int i = 0; i<NR_COLUMN_LOCKS; i++)
@@ -3225,6 +3215,7 @@ func_dup(sql_trans *tr, sql_func *of, sq
f->query = (of->query)?SA_STRDUP(sa, of->query):NULL;
f->s = s;
f->sa = sa;
+ MT_lock_init(&f->function_lock, "function_lock");
f->ops = SA_LIST(sa, (fdestroy) &arg_destroy);
for (node *n=of->ops->h; n; n = n->next)
@@ -4848,6 +4839,8 @@ create_sql_func(sqlstore *store, sql_all
t->fix_scale = SCALE_EQ;
t->s = NULL;
t->system = system;
+ if (!t->instantiated)
+ MT_lock_init(&t->function_lock, "function_lock");
return t;
}
@@ -4885,6 +4878,8 @@ sql_trans_create_func(sql_func **fres, s
}
t->query = (query)?SA_STRDUP(tr->sa, query):NULL;
t->s = s;
+ if (!t->instantiated)
+ MT_lock_init(&t->function_lock, "function_lock");
if ((res = os_add(s->funcs, tr, t->base.name, &t->base)))
return res;
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list