txlyre 12 hours ago
parent
commit
a21ad7ded5
2 changed files with 195 additions and 124 deletions
  1. 167 110
      qirt.c
  2. 28 14
      qirt.h

+ 167 - 110
qirt.c

@@ -583,7 +583,7 @@ void qi_new_scope(qi_state_t *state) {
 
   scope->is_barrier = false;
 
-  scope->lock = qi_lock_create();
+  scope->mutex = qi_mutex_create();
 
   qi_list_push(state->scopes, scope);
 }
@@ -638,10 +638,10 @@ void qi_value_finalizer(GC_PTR _value, GC_PTR _state) {
   }
 
   if (value->type == QI_TABLE || value->type == QI_LIST) {
-    if (value->lock)
-      qi_lock_destroy(value->lock);
+    if (value->mutex)
+      qi_mutex_destroy(value->mutex);
 
-    value->lock = NULL;
+    value->mutex = NULL;
   }
 }
 
@@ -654,7 +654,7 @@ qi_value_t *qi_make_value(qi_type_t type) {
     value = qi_malloc(sizeof(qi_value_t));
 
   value->type = type;
-  value->lock = NULL;
+  value->mutex = NULL;
 
   return value;
 }
@@ -688,11 +688,11 @@ qi_value_t *qi_make_string(qi_state_t *state, char *string) {
   if (len == 0)
     return state->empty_string;
   else if (len <= 24) {
-    qi_lock_acquire(state->intern_strs_lock);
+    qi_mutex_lock(state->intern_strs_mutex);
 
     value = qi_table_get(state->intern_strs, string);
 
-    qi_lock_release(state->intern_strs_lock);
+    qi_mutex_unlock(state->intern_strs_mutex);
 
     if (value)
       return value;
@@ -702,11 +702,11 @@ qi_value_t *qi_make_string(qi_state_t *state, char *string) {
   value->value.string = string;
 
   if (len <= 24) {
-    qi_lock_acquire(state->intern_strs_lock);
+    qi_mutex_lock(state->intern_strs_mutex);
 
     qi_table_set(state->intern_strs, string, value);
 
-    qi_lock_release(state->intern_strs_lock);
+    qi_mutex_unlock(state->intern_strs_mutex);
   }
 
   return value;
@@ -755,7 +755,7 @@ qi_value_t *qi_make_file(qi_state_t *state, FILE *file, char *mode) {
 
 qi_value_t *qi_make_list(qi_state_t *state, qi_list_t *list) {
   qi_value_t *value = qi_make_value(QI_LIST);
-  value->lock = qi_lock_create();
+  value->mutex = qi_mutex_create();
   value->value.list = !list? qi_list_make(): list;
 
   GC_register_finalizer(value, qi_value_finalizer, (void *)state, NULL, NULL);
@@ -777,7 +777,7 @@ qi_value_t *qi_make_tuple(qi_state_t *state, qi_list_t *tuple) {
 
 qi_value_t *qi_make_table(qi_state_t *state, qi_table_t *table) {
   qi_value_t *value = qi_make_value(QI_TABLE);
-  value->lock = qi_lock_create();
+  value->mutex = qi_mutex_create();
   value->value.table.table = !table? qi_table_make(): table;
   value->value.table.metatable = state->nil;
 
@@ -824,7 +824,7 @@ qi_value_t *qi_make_data(qi_state_t *state, unsigned int tag, void *data) {
 
 static qi_value_t *qi_get_pseudomethod(qi_state_t *state, qi_value_t *value,
                                        char *name) {
-  qi_lock_acquire(state->pseudomethods_lock);
+  qi_mutex_lock(state->pseudomethods_mutex);
 
   char pseudomethod_name[64];
   snprintf(pseudomethod_name, sizeof(pseudomethod_name), "%s.%s",
@@ -832,7 +832,7 @@ static qi_value_t *qi_get_pseudomethod(qi_state_t *state, qi_value_t *value,
 
   qi_value_t *meta = qi_table_get(state->pseudomethods, pseudomethod_name);
 
-  qi_lock_release(state->pseudomethods_lock);
+  qi_mutex_unlock(state->pseudomethods_mutex);
 
   return meta;
 }
@@ -842,11 +842,11 @@ qi_value_t *qi_add_pseudomethod(qi_state_t *state, char *name, qi_size_t pargc,
   qi_value_t *method = qi_make_function(state, name, pargc + 1, handle, NULL);
   method->value.function.is_pm = true;
 
-  qi_lock_acquire(state->pseudomethods_lock);
+  qi_mutex_lock(state->pseudomethods_mutex);
 
   qi_table_set(state->pseudomethods, name, method);
 
-  qi_lock_release(state->pseudomethods_lock);
+  qi_mutex_unlock(state->pseudomethods_mutex);
 
   return method;
 }
@@ -923,15 +923,15 @@ char *_qi_type(qi_state_t *state, qi_value_t *value) {
   }
 
   if (value->type == QI_TABLE) {
-    qi_lock_acquire(value->lock);
+    qi_mutex_lock(value->mutex);
 
     if (qi_has_metatable(value)) {
-      qi_lock_release(value->lock);
+      qi_mutex_unlock(value->mutex);
 
       return (char *)qi_repr_type(QI_OBJECT);
     }
 
-    qi_lock_release(value->lock);
+    qi_mutex_unlock(value->mutex);
   }
 
   return (char *)qi_repr_type(value->type);
@@ -1097,7 +1097,7 @@ char *_qi_repr(qi_state_t *state, qi_list_t *tempstack, qi_value_t *value,
 
     LOCKED(value, {
       if (qi_list_empty(value->value.list)) {
-        qi_lock_release(value->lock);
+        qi_mutex_unlock(value->mutex);
 
         return qi_strdup("[]");
       }
@@ -1158,7 +1158,7 @@ char *_qi_repr(qi_state_t *state, qi_list_t *tempstack, qi_value_t *value,
 
     LOCKED(value, {
       if (qi_table_empty(value->value.table.table)) {
-        qi_lock_release(value->lock);
+        qi_mutex_unlock(value->mutex);
 
         return qi_strdup(qi_has_metatable(value) ? "<object {}>" : "{}");
       }
@@ -1346,11 +1346,11 @@ qi_value_t *qi_find(qi_state_t *state, char *name) {
       if (scope->is_barrier)
         continue;
 
-      qi_lock_acquire(scope->lock);
+      qi_mutex_lock(scope->mutex);
 
       qi_symbol_t *symbol = qi_table_get(scope->scope, name);
 
-      qi_lock_release(scope->lock);
+      qi_mutex_unlock(scope->mutex);
 
       if (symbol)
         return symbol->value;
@@ -1390,13 +1390,13 @@ static void _qi_decl(qi_state_t *state, char *name, qi_value_t *value,
   qi_scope_t *scope = qi_list_last(state->scopes);
   qi_symbol_t *symbol;
 
-  qi_lock_acquire(scope->lock);
+  qi_mutex_lock(scope->mutex);
 
   symbol = qi_table_get(scope->scope, name);
 
   if (symbol) {
     if (is_constant || symbol->is_constant) {
-      qi_lock_release(scope->lock);
+      qi_mutex_unlock(scope->mutex);
 
       qi_throw_format(state, "redeclaration of constant symbol: '%s'", name);
     }
@@ -1410,7 +1410,7 @@ static void _qi_decl(qi_state_t *state, char *name, qi_value_t *value,
     qi_table_set(scope->scope, name, symbol);
   }
 
-  qi_lock_release(scope->lock);
+  qi_mutex_unlock(scope->mutex);
 }
 
 void qi_decl_const(qi_state_t *state, char *name, qi_value_t *value) {
@@ -1431,13 +1431,13 @@ qi_value_t *_qi_set(qi_state_t *state, bool is_pf, bool is_constant,
       if (scope->is_barrier)
         continue;
 
-      qi_lock_acquire(scope->lock);
+      qi_mutex_lock(scope->mutex);
 
       qi_symbol_t *symbol = qi_table_get(scope->scope, name);
 
       if (symbol) {
         if (is_constant || symbol->is_constant) {
-          qi_lock_release(scope->lock);
+          qi_mutex_unlock(scope->mutex);
 
           qi_throw_format(state, "redeclaration of constant symbol: '%s'",
                           name);
@@ -1447,12 +1447,12 @@ qi_value_t *_qi_set(qi_state_t *state, bool is_pf, bool is_constant,
 
         symbol->value = value;
 
-        qi_lock_release(scope->lock);
+        qi_mutex_unlock(scope->mutex);
 
         return !is_pf && old ? old : value;
       }
 
-      qi_lock_release(scope->lock);
+      qi_mutex_unlock(scope->mutex);
     }
 
   qi_symbol_t *symbol = qi_malloc(sizeof(qi_symbol_t));
@@ -1461,11 +1461,11 @@ qi_value_t *_qi_set(qi_state_t *state, bool is_pf, bool is_constant,
 
   qi_scope_t *scope = qi_list_last(state->scopes);
 
-  qi_lock_acquire(scope->lock);
+  qi_mutex_lock(scope->mutex);
 
   qi_table_set(scope->scope, name, symbol);
 
-  qi_lock_release(scope->lock);
+  qi_mutex_unlock(scope->mutex);
 
   return value;
 }
@@ -1693,7 +1693,7 @@ qi_value_t *qi_cast(qi_state_t *state, qi_type_t type, qi_value_t *value) {
             qi_value_t *byte = qi_list_data(list, i);
 
             if (byte->type != QI_NUMBER) {
-              qi_lock_release(value->lock);
+              qi_mutex_unlock(value->mutex);
 
               qi_throw_format(state,
                               "cannot cast %s to %s (expected list of numbers, but element #%zu is %s)",
@@ -1782,7 +1782,7 @@ qi_value_t *qi_cast(qi_state_t *state, qi_type_t type, qi_value_t *value) {
       qi_table_t *table = qi_table_make();
 
       if (value->type == QI_LIST)
-        qi_lock_acquire(value->lock);
+        qi_mutex_lock(value->mutex);
 
       qi_list_t *list = value->value.list;
       if (!qi_list_empty(list))
@@ -1790,14 +1790,14 @@ qi_value_t *qi_cast(qi_state_t *state, qi_type_t type, qi_value_t *value) {
           qi_value_t *pair = qi_list_data(list, i);
 
           if (pair->type == QI_LIST)
-            qi_lock_acquire(pair->lock);
+            qi_mutex_lock(pair->mutex);
 
           if ((pair->type != QI_LIST && pair->type != QI_TUPLE) ||
               qi_list_length(pair->value.list) != 2) {
             if (value->type == QI_LIST)
-              qi_lock_release(value->lock);
+              qi_mutex_unlock(value->mutex);
             if (pair->type == QI_LIST)
-              qi_lock_release(pair->lock);
+              qi_mutex_unlock(pair->mutex);
 
             qi_throw_format(state,
                             "cannot cast %s to %s (expected sequence of pairs)",
@@ -1808,9 +1808,9 @@ qi_value_t *qi_cast(qi_state_t *state, qi_type_t type, qi_value_t *value) {
 
           if (left->type != QI_STRING) {
             if (value->type == QI_LIST)
-              qi_lock_release(value->lock);
+              qi_mutex_unlock(value->mutex);
             if (pair->type == QI_LIST)
-              qi_lock_release(pair->lock);
+              qi_mutex_unlock(pair->mutex);
 
             qi_throw_format(state,
                             "cannot cast %s to %s (expected first element of "
@@ -1821,13 +1821,13 @@ qi_value_t *qi_cast(qi_state_t *state, qi_type_t type, qi_value_t *value) {
           qi_value_t *right = qi_list_data(pair->value.list, 1);
 
           if (pair->type == QI_LIST)
-            qi_lock_release(pair->lock);
+            qi_mutex_unlock(pair->mutex);
 
           qi_table_set(table, left->value.string, right);
         }
 
       if (value->type == QI_LIST)
-        qi_lock_release(value->lock);
+        qi_mutex_unlock(value->mutex);
 
       return qi_make_table(state, table);
     }
@@ -2205,19 +2205,19 @@ bool _qi_equals(qi_state_t *state, qi_value_t *a, qi_value_t *b) {
     return fileno(a->value.file.fd) == fileno(b->value.file.fd);
 
   case QI_LIST:
-    qi_lock_acquire(a->lock);
-    qi_lock_acquire(b->lock);
+    qi_mutex_lock(a->mutex);
+    qi_mutex_lock(b->mutex);
 
     if (a->value.list == b->value.list) {
-      qi_lock_release(a->lock);
-      qi_lock_release(b->lock);
+      qi_mutex_unlock(a->mutex);
+      qi_mutex_unlock(b->mutex);
 
       return true;
     }
 
     if (qi_list_length(a->value.list) != qi_list_length(b->value.list)) {
-      qi_lock_release(a->lock);
-      qi_lock_release(b->lock);
+      qi_mutex_unlock(a->mutex);
+      qi_mutex_unlock(b->mutex);
 
       return false;
     }
@@ -2225,14 +2225,14 @@ bool _qi_equals(qi_state_t *state, qi_value_t *a, qi_value_t *b) {
     for (qi_size_t i = 0; i < qi_list_length(a->value.list); i++)
       if (!_qi_equals(state, qi_list_index(a->value.list, i),
                       qi_list_index(b->value.list, i))) {
-        qi_lock_release(a->lock);
-        qi_lock_release(b->lock);
+        qi_mutex_unlock(a->mutex);
+        qi_mutex_unlock(b->mutex);
 
         return false;
       }
 
-    qi_lock_release(a->lock);
-    qi_lock_release(b->lock);
+    qi_mutex_unlock(a->mutex);
+    qi_mutex_unlock(b->mutex);
 
     return true;
 
@@ -2251,20 +2251,20 @@ bool _qi_equals(qi_state_t *state, qi_value_t *a, qi_value_t *b) {
     return true;
 
   case QI_TABLE:
-    qi_lock_acquire(a->lock);
-    qi_lock_acquire(b->lock);
+    qi_mutex_lock(a->mutex);
+    qi_mutex_lock(b->mutex);
 
     if (a->value.table.table == b->value.table.table) {
-      qi_lock_release(a->lock);
-      qi_lock_release(b->lock);
+      qi_mutex_unlock(a->mutex);
+      qi_mutex_unlock(b->mutex);
 
       return true;
     }
 
     if (qi_table_length(a->value.table.table) !=
         qi_table_length(b->value.table.table)) {
-      qi_lock_release(a->lock);
-      qi_lock_release(b->lock);
+      qi_mutex_unlock(a->mutex);
+      qi_mutex_unlock(b->mutex);
 
       return false;
     }
@@ -2273,22 +2273,22 @@ bool _qi_equals(qi_state_t *state, qi_value_t *a, qi_value_t *b) {
       qi_value_t *a_value = entry.value;
       qi_value_t *b_value = qi_table_get(b->value.table.table, entry.key);
       if (!b_value) {
-        qi_lock_release(a->lock);
-        qi_lock_release(b->lock);
+        qi_mutex_unlock(a->mutex);
+        qi_mutex_unlock(b->mutex);
 
         return false;
       }
 
       if (!_qi_equals(state, a_value, b_value)) {
-        qi_lock_release(a->lock);
-        qi_lock_release(b->lock);
+        qi_mutex_unlock(a->mutex);
+        qi_mutex_unlock(b->mutex);
 
         return false;
       }
     });
 
-    qi_lock_release(a->lock);
-    qi_lock_release(b->lock);
+    qi_mutex_unlock(a->mutex);
+    qi_mutex_unlock(b->mutex);
 
     return true;
 
@@ -2335,14 +2335,14 @@ bool _qi_in(qi_state_t *state, qi_value_t *a, qi_value_t *b) {
       qi_list_t *list = b->value.list;
 
       if (qi_list_empty(list)) {
-        qi_lock_release(b->lock);
+        qi_mutex_unlock(b->mutex);
 
         return false;
       }
 
       for (qi_size_t i = 0; i < qi_list_length(list); i++)
         if (_qi_equals(state, a, qi_list_data(list, i))) {
-          qi_lock_release(b->lock);
+          qi_mutex_unlock(b->mutex);
 
           return true;
         }
@@ -2436,21 +2436,21 @@ qi_value_t *qi_add(qi_state_t *state, qi_value_t *a, qi_value_t *b) {
     qi_list_t *newlist = qi_list_make();
 
     if (a->type == QI_LIST) {
-      qi_lock_acquire(a->lock);
-      qi_lock_acquire(b->lock);
+      qi_mutex_lock(a->mutex);
+      qi_mutex_lock(b->mutex);
     }
 
     for (qi_size_t i = 0; i < qi_list_length(a->value.list); i++)
       qi_list_push(newlist, qi_list_data(a->value.list, i));
 
     if (a->type == QI_LIST)
-      qi_lock_release(a->lock);
+      qi_mutex_unlock(a->mutex);
 
     for (qi_size_t i = 0; i < qi_list_length(b->value.list); i++)
       qi_list_push(newlist, qi_list_data(b->value.list, i));
 
     if (a->type == QI_LIST)
-      qi_lock_release(b->lock);
+      qi_mutex_unlock(b->mutex);
 
     if (a->type == QI_TUPLE)
       return qi_make_tuple(state, newlist);
@@ -2459,18 +2459,18 @@ qi_value_t *qi_add(qi_state_t *state, qi_value_t *a, qi_value_t *b) {
   } else if (a->type == QI_TABLE && b->type == QI_TABLE) {
     qi_table_t *newtable = qi_table_make();
 
-    qi_lock_acquire(a->lock);
-    qi_lock_acquire(b->lock);
+    qi_mutex_lock(a->mutex);
+    qi_mutex_lock(b->mutex);
 
     qi_table_iterate(a->value.table.table,
                      { qi_table_set(newtable, entry.key, entry.value); });
 
-    qi_lock_release(a->lock);
+    qi_mutex_unlock(a->mutex);
 
     qi_table_iterate(b->value.table.table,
                      { qi_table_set(newtable, entry.key, entry.value); });
 
-    qi_lock_release(b->lock);
+    qi_mutex_unlock(b->mutex);
 
     return qi_make_table(state, newtable);
   } else if (a->type == QI_NUMBER && b->type == QI_NUMBER)
@@ -2841,7 +2841,7 @@ static void qi_set_barrier(qi_state_t *state) {
   scope->scope = NULL;
   scope->defers = NULL;
   scope->is_barrier = true;
-  scope->lock = NULL;
+  scope->mutex = NULL;
 
   qi_list_push(state->scopes, scope);
 }
@@ -2914,7 +2914,7 @@ qi_value_t *qi_thread_join(qi_state_t *state, void *_td) {
   return ret;
 }
 
-void *qi_lock_create(void) {
+void *qi_mutex_create(void) {
   pthread_mutex_t *mutex = qi_malloc_atomic(sizeof(pthread_mutex_t));
   if (pthread_mutex_init(mutex, NULL) != 0)
     return NULL;
@@ -2922,38 +2922,95 @@ void *qi_lock_create(void) {
   return (void *)mutex;
 }
 
-void qi_lock_destroy(void *lock) {
-  pthread_mutex_t *mutex = (pthread_mutex_t *)lock;
-  pthread_mutex_destroy(mutex);
+void qi_mutex_destroy(void *mutex) {
+  pthread_mutex_destroy((pthread_mutex_t *)mutex);
 }
 
-bool qi_lock_acquired(void *lock) {
-  pthread_mutex_t *mutex = (pthread_mutex_t *)lock;
-  if (pthread_mutex_trylock(mutex) == 0) {
-    pthread_mutex_unlock(mutex);
+void qi_mutex_lock(void *mutex) {
+  pthread_mutex_lock((pthread_mutex_t *)mutex);
+}
+
+bool qi_mutex_trylock(void *mutex) {
+  if (pthread_mutex_trylock((pthread_mutex_t *)mutex) == 0)
+    return true;
+
+  return false;
+}
+
+void qi_mutex_unlock(void *mutex) {
+  pthread_mutex_unlock((pthread_mutex_t *)mutex);
+}
+
+qi_lock_t *qi_lock_create(void) {
+  qi_lock_t *lock = qi_malloc(sizeof(qi_lock_t));
+  lock->locked = false;
+
+  lock->mutex = qi_mutex_create();
+  if (!lock->mutex)
+    return NULL;
+
+  pthread_cond_t *cond = qi_malloc(sizeof(pthread_cond_t));
+  if (pthread_cond_init(cond, NULL) != 0)
+    return NULL;
+
+  lock->cond = (void *)cond;
+
+  return lock;
+}
+
+void qi_lock_destroy(qi_lock_t *lock) {
+  qi_mutex_destroy(lock->mutex);
+  pthread_cond_destroy((pthread_cond_t *)lock->cond);
+}
+
+void qi_lock_acquire(qi_lock_t *lock) {
+  qi_mutex_lock(lock->mutex);
+
+  while (lock->locked)
+    pthread_cond_wait((pthread_cond_t *)lock->cond, (pthread_mutex_t *)lock->mutex);
+
+  lock->locked = true;
+
+  qi_mutex_unlock(lock->mutex);
+}
+
+bool qi_lock_tryacquire(qi_lock_t *lock) {
+  qi_mutex_lock(lock->mutex);
+
+  if (lock->locked) {
+    qi_mutex_unlock(lock->mutex);
 
     return false;
   }
 
+  while (lock->locked)
+    pthread_cond_wait((pthread_cond_t *)lock->cond, (pthread_mutex_t *)lock->mutex);
+
+  lock->locked = true;
+
+  qi_mutex_unlock(lock->mutex);
+
   return true;
 }
 
-void qi_lock_acquire(void *lock) {
-  pthread_mutex_t *mutex = (pthread_mutex_t *)lock;
-  pthread_mutex_lock(mutex);
-}
+bool qi_lock_acquired(qi_lock_t *lock) {
+  qi_mutex_lock(lock->mutex);
 
-bool qi_lock_tryacquire(void *lock) {
-  pthread_mutex_t *mutex = (pthread_mutex_t *)lock;
-  if (pthread_mutex_trylock(mutex) == 0)
-    return true;
+  bool res = lock->locked;
 
-  return false;
+  qi_mutex_unlock(lock->mutex);
+
+  return res;
 }
 
-void qi_lock_release(void *lock) {
-  pthread_mutex_t *mutex = (pthread_mutex_t *)lock;
-  pthread_mutex_unlock(mutex);
+void qi_lock_release(qi_lock_t *lock) {
+  qi_mutex_lock(lock->mutex);
+
+  lock->locked = false;
+
+  pthread_cond_signal((pthread_cond_t *)lock->cond);
+
+  qi_mutex_unlock(lock->mutex);
 }
 
 qi_value_t *qi_builtin_print(qi_state_t *state, qi_size_t pargc,
@@ -3088,7 +3145,7 @@ qi_value_t *qi_builtin_delete_method(qi_state_t *state, qi_size_t pargc,
   LOCKED(a, {
     if (qi_has_metatable(a))
       if (!qi_table_delete(qi_get_metatable(a), b->value.string)) {
-        qi_lock_release(a->lock);
+        qi_mutex_unlock(a->mutex);
 
         qi_throw_format(state, "no such method: '%s'", b->value.string);
       }
@@ -3115,11 +3172,11 @@ qi_value_t *qi_builtin_set_pseudomethod(qi_state_t *state, qi_size_t pargc,
   qi_value_t *method = qi_make_function(state, name, b->value.function.pargc, b->value.function.handle, NULL);
   method->value.function.is_pm = true;
 
-  qi_lock_acquire(state->pseudomethods_lock);
+  qi_mutex_lock(state->pseudomethods_mutex);
 
   qi_table_set(state->pseudomethods, name, method);
 
-  qi_lock_release(state->pseudomethods_lock);
+  qi_mutex_unlock(state->pseudomethods_mutex);
 
   return method;
 }
@@ -3132,11 +3189,11 @@ qi_value_t *qi_builtin_has_pseudomethod(qi_state_t *state, qi_size_t pargc,
     qi_throw_format(state, "expected first argument to be: string, but got: %s",
                     _qi_type(state, a));
 
-  qi_lock_acquire(state->pseudomethods_lock);
+  qi_mutex_lock(state->pseudomethods_mutex);
 
   bool res = qi_table_has(state->pseudomethods, a->value.string);
 
-  qi_lock_release(state->pseudomethods_lock);
+  qi_mutex_unlock(state->pseudomethods_mutex);
 
   return res? state->_true: state->_false;
 }
@@ -3149,11 +3206,11 @@ qi_value_t *qi_builtin_unset_pseudomethod(qi_state_t *state, qi_size_t pargc,
     qi_throw_format(state, "expected first argument to be: string, but got: %s",
                     _qi_type(state, a));
 
-  qi_lock_acquire(state->pseudomethods_lock);
+  qi_mutex_lock(state->pseudomethods_mutex);
 
   bool res = qi_table_delete(state->pseudomethods, a->value.string);
 
-  qi_lock_release(state->pseudomethods_lock);
+  qi_mutex_unlock(state->pseudomethods_mutex);
 
   if (!res)
     qi_throw_format(state, "no such pseudomethod: '%s'", a->value.string);
@@ -3192,12 +3249,12 @@ qi_value_t *qi_builtin_set_global(qi_state_t *state, qi_size_t pargc,
   } else
     scope = qi_list_first(state->scopes);
 
-  qi_lock_acquire(scope->lock);
+  qi_mutex_lock(scope->mutex);
 
   symbol = qi_table_get(scope->scope, name);
   if (symbol) {
     if (symbol->is_constant) {
-      qi_lock_release(scope->lock);
+      qi_mutex_unlock(scope->mutex);
 
       qi_throw_format(state, "redeclaration of constant symbol: '%s'", name);
     }
@@ -3205,7 +3262,7 @@ qi_value_t *qi_builtin_set_global(qi_state_t *state, qi_size_t pargc,
     qi_value_t *ret = symbol->value;
     symbol->value = b;
 
-    qi_lock_release(scope->lock);
+    qi_mutex_unlock(scope->mutex);
 
     return ret;
   }
@@ -3216,7 +3273,7 @@ qi_value_t *qi_builtin_set_global(qi_state_t *state, qi_size_t pargc,
 
   qi_table_set(scope->scope, name, symbol);
 
-  qi_lock_release(scope->lock);
+  qi_mutex_unlock(scope->mutex);
 
   return b;
 }
@@ -3252,14 +3309,14 @@ qi_value_t *qi_builtin_get_global(qi_state_t *state, qi_size_t pargc,
   } else
     scope = qi_list_first(state->scopes);
 
-  qi_lock_acquire(scope->lock);
+  qi_mutex_lock(scope->mutex);
 
   qi_symbol_t *symbol = qi_table_get(scope->scope, name);
 
   if (symbol)
     ret = symbol->value;
 
-  qi_lock_release(scope->lock);
+  qi_mutex_unlock(scope->mutex);
 
   return ret;
 }
@@ -3270,7 +3327,7 @@ qi_value_t *qi_builtin_get_globals(qi_state_t *state, qi_size_t pargc,
 
   qi_scope_t *scope = qi_list_first(state->scopes);
 
-  qi_lock_acquire(scope->lock);
+  qi_mutex_lock(scope->mutex);
 
   qi_table_iterate(scope->scope, {
     qi_symbol_t *symbol = entry.value;
@@ -3278,7 +3335,7 @@ qi_value_t *qi_builtin_get_globals(qi_state_t *state, qi_size_t pargc,
     qi_table_set(table, entry.key, symbol->value);
   });
 
-  qi_lock_release(scope->lock);
+  qi_mutex_unlock(scope->mutex);
 
   return qi_make_table(state, table);
 }
@@ -3959,10 +4016,10 @@ static void qi_state_setup(qi_state_t *state) {
   }
 
   state->intern_strs = qi_table_make();
-  state->intern_strs_lock = qi_lock_create();
+  state->intern_strs_mutex = qi_mutex_create();
 
   state->pseudomethods = qi_table_make();
-  state->pseudomethods_lock = qi_lock_create();
+  state->pseudomethods_mutex = qi_mutex_create();
 
   state->nan = qi_make_value(QI_NUMBER);
   state->nan->value.number = NAN;

+ 28 - 14
qirt.h

@@ -109,7 +109,7 @@ typedef struct {
 
 struct _qi_value_t {
   qi_type_t type;
-  void *lock;
+  void *mutex;
 
   union {
     bool boolean;
@@ -165,10 +165,10 @@ struct _qi_state_t {
   qi_value_t *numbers[256];
 
   qi_table_t *pseudomethods;
-  void *pseudomethods_lock;
+  void *pseudomethods_mutex;
 
   qi_table_t *intern_strs;
-  void *intern_strs_lock;
+  void *intern_strs_mutex;
 
   qi_list_t *traps;
   qi_list_t *scopes;
@@ -185,7 +185,7 @@ struct _qi_scope_t {
 
   bool is_barrier;
 
-  void *lock;
+  void *mutex;
 };
 
 typedef void (*qi_defer_t)(qi_state_t *);
@@ -246,6 +246,15 @@ struct _qi_symbol_t {
   bool is_constant;
 };
 
+typedef struct _qi_lock_t qi_lock_t;
+
+struct _qi_lock_t {
+  bool locked;
+
+  void *mutex;
+  void *cond;
+};
+
 #define qi_set(state, is_pf, name, value)                                     \
   (_qi_set((state), is_pf, false, (name), (value)))
 #define qi_bind(state, is_pf, name, value)                                    \
@@ -330,11 +339,11 @@ struct _qi_symbol_t {
 
 #define LOCKED(value, code)                                                    \
   {                                                                            \
-    if ((value)->lock)                                                         \
-      qi_lock_acquire((value)->lock);                                          \
+    if ((value)->mutex)                                                         \
+      qi_mutex_lock((value)->mutex);                                          \
     code;                                                                      \
-    if ((value)->lock)                                                         \
-      qi_lock_release((value)->lock);                                          \
+    if ((value)->mutex)                                                         \
+      qi_mutex_unlock((value)->mutex);                                          \
   }
 
 void *qi_malloc(qi_size_t size);
@@ -434,12 +443,17 @@ void *qi_thread_create(qi_state_t *state, qi_value_t *fn, qi_list_t *args);
 qi_value_t *qi_thread_join(qi_state_t *state, void *td);
 void qi_thread_exit(qi_state_t *state, qi_value_t *value);
 bool qi_thread_main(void);
-void *qi_lock_create(void);
-void qi_lock_destroy(void *lock);
-void qi_lock_acquire(void *lock);
-bool qi_lock_tryacquire(void *lock);
-bool qi_lock_acquired(void *lock);
-void qi_lock_release(void *lock);
+void *qi_mutex_create(void);
+void qi_mutex_destroy(void *mutex);
+void qi_mutex_lock(void *mutex);
+bool qi_mutex_trylock(void *mutex);
+void qi_mutex_unlock(void *mutex);
+qi_lock_t *qi_lock_create(void);
+void qi_lock_destroy(qi_lock_t *lock);
+void qi_lock_acquire(qi_lock_t *lock);
+bool qi_lock_tryacquire(qi_lock_t *lock);
+bool qi_lock_acquired(qi_lock_t *lock);
+void qi_lock_release(qi_lock_t *lock);
 void qi_state_init(qi_state_t **state);
 void qi_state_init_debug(qi_state_t **state);