// global state
struct ggml_state g_state;
+atomic_bool g_state_barrier = 0;
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
struct ggml_context * ggml_init(struct ggml_init_params params) {
+ // make this function thread safe
+ {
+ int processing = atomic_fetch_add(&g_state_barrier, 1);
+ while (processing > 0) {
+ // wait for other threads to finish
+ atomic_fetch_sub(&g_state_barrier, 1);
+ sched_yield();
+ processing = atomic_fetch_add(&g_state_barrier, 1);
+ }
+ }
+
static bool is_first_call = true;
if (is_first_call) {
const uint64_t t_start = ggml_time_us(); UNUSED(t_start);
if (ctx == NULL) {
GGML_PRINT_DEBUG("%s: no unused context found\n", __func__);
+
+ atomic_fetch_sub(&g_state_barrier, 1);
+
return NULL;
}
ggml_assert_aligned(ctx->mem_buffer);
+ GGML_PRINT_DEBUG("%s: context initialized\n", __func__);
+
+ atomic_fetch_sub(&g_state_barrier, 1);
+
return ctx;
}
void ggml_free(struct ggml_context * ctx) {
+ // make this function thread safe
+ {
+ int processing = atomic_fetch_add(&g_state_barrier, 1);
+ while (processing > 0) {
+ // wait for other threads to finish
+ atomic_fetch_sub(&g_state_barrier, 1);
+ sched_yield();
+ processing = atomic_fetch_add(&g_state_barrier, 1);
+ }
+ }
+
for (int i = 0; i < GGML_MAX_CONTEXTS; i++) {
if (&g_state.contexts[i].context == ctx) {
g_state.contexts[i].used = false;
free(ctx->mem_buffer);
}
+ atomic_fetch_sub(&g_state_barrier, 1);
+
return;
}
}
GGML_PRINT_DEBUG("%s: context not found\n", __func__);
+
+ atomic_fetch_sub(&g_state_barrier, 1);
}
size_t ggml_used_mem(const struct ggml_context * ctx) {