Skip to content

Commit

Permalink
various bug fixes, corrections, update dependency
Browse files Browse the repository at this point in the history
-  `thrd_for` example now execute as expected
  • Loading branch information
TheTechsTech committed Nov 30, 2024
1 parent f69a583 commit a033f27
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 47 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ else()
endif()

FetchContent_Declare(threads
URL https://github.com/zelang-dev/cthread/archive/refs/tags/v4.1.0.0.zip
URL_MD5 b94418e2efd06782e7ddf81a7c1a7e40
URL https://github.com/zelang-dev/cthread/archive/refs/tags/v4.1.0.1.zip
URL_MD5 5392e7fac2638e1e54e5920ebf289096
)
FetchContent_MakeAvailable(threads)

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -318,8 +318,8 @@ C_API uintptr_t thrd_self(void);
C_API raii_values_t *thrd_value(uintptr_t value);

C_API future_t *thrd_for(thrd_func_t fn, size_t times, const char *desc, ...);
C_API thrd_values *thrd_sync(future_t *);
C_API values_type thrd_then(result_func_t callback, thrd_values *iter, void_t result);
C_API thrd_values_t *thrd_sync(future_t *);
C_API values_type thrd_then(result_func_t callback, thrd_values_t *iter, void_t result);
C_API bool thrd_is_finish(future_t *);
C_API future_t thrd_add(future_t *, thrd_func_t routine, const char *desc, ...);
C_API void thrd_destroy(future_t *);
Expand Down
4 changes: 2 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -313,8 +313,8 @@ C_API uintptr_t thrd_self(void);
C_API raii_values_t *thrd_value(uintptr_t value);

C_API future_t *thrd_for(thrd_func_t fn, size_t times, const char *desc, ...);
C_API thrd_values *thrd_sync(future_t *);
C_API values_type thrd_then(result_func_t callback, thrd_values *iter, void_t result);
C_API thrd_values_t *thrd_sync(future_t *);
C_API values_type thrd_then(result_func_t callback, thrd_values_t *iter, void_t result);
C_API bool thrd_is_finish(future_t *);
C_API future_t thrd_add(future_t *, thrd_func_t routine, const char *desc, ...);
C_API void thrd_destroy(future_t *);
Expand Down
11 changes: 6 additions & 5 deletions examples/thrd_for.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@

void *is_prime(args_t arg) {
int i, x = get_args(arg, 0).integer;
printf("\nThread #%zx, received: %d\n", thrd_self(), x);
printf("Thread #%zx, received: %d\n", thrd_self(), x);
for (i = 2; i < x; ++i) if (x % i == 0) return thrd_value(false);

return thrd_value(true);
}

void_t check_primes(void_t result, size_t id, values_type iter) {
if (iter.boolean)
printf("Number %zu is prime.\n", id);
printf("Thread %zu: is prime.\n", id);
else
printf("Number %zu is not prime.\n", id);
printf("Thread %zu: is not prime.\n", id);

return iter.object;
return 0;
}

int main(int argc, char **argv) {
Expand All @@ -25,7 +25,8 @@ int main(int argc, char **argv) {
if (!thrd_is_finish(fut))
printf("checking...\n");

result->object = thrd_then(check_primes, thrd_sync(fut), result).object;
thrd_then(check_primes, thrd_sync(fut), result);
thrd_destroy(fut);

return 0;
}
26 changes: 9 additions & 17 deletions include/raii.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ typedef union {

typedef struct {
values_type value;
raii_type type;
} raii_values_t;

typedef struct {
Expand Down Expand Up @@ -167,15 +166,12 @@ struct memory_s {

typedef struct args_s {
raii_type type;
bool defer_set;
bool data_set;
int defer_set;

unique_t *context;
size_t args_size;
/* total number of args in set */
size_t n_args;
size_t data_size;

unique_t *context;
void_t data;

/* allocated array of arguments */
raii_values_t *args;
Expand All @@ -184,7 +180,6 @@ typedef struct args_s {
typedef void_t (*thrd_func_t)(args_t);
typedef void_t (*result_func_t)(void_t result, size_t id, values_type iter);
typedef void (*wait_func)(void);
make_atomic(c89atomic_spinlock, atomic_spinlock)
typedef struct _promise {
raii_type type;
int id;
Expand All @@ -198,7 +193,7 @@ typedef struct {
int id;
size_t value_count;
raii_values_t **values;
} thrd_values;
} thrd_values_t;

typedef struct _future_arg future_arg;
typedef struct future_deque future_deque_t;
Expand Down Expand Up @@ -227,6 +222,7 @@ struct future_deque {
typedef struct future_pool {
raii_type type;
int thread_count;
memory_t *scope;
future **futures;
future_deque_t queue[1];
} future_t;
Expand All @@ -237,7 +233,6 @@ struct _future {
thrd_t thread;
thrd_func_t func;
promise *value;
future_t *pool;
};

/* Calls fn (with args as arguments) in separate thread, returning without waiting
Expand All @@ -260,14 +255,11 @@ C_API uintptr_t thrd_self(void);
C_API raii_values_t *thrd_value(uintptr_t value);

C_API future_t *thrd_for(thrd_func_t fn, size_t times, const char *desc, ...);
C_API thrd_values *thrd_sync(future_t *);
C_API values_type thrd_then(result_func_t callback, thrd_values *iter, void_t result);
C_API bool thrd_is_finish(future_t *);
C_API future_t thrd_add(future_t *, thrd_func_t routine, const char *desc, ...);
C_API thrd_values_t *thrd_sync(future_t *);
C_API int thrd_add(future_t *, thrd_func_t routine, const char *desc, ...);
C_API void thrd_then(result_func_t callback, thrd_values_t *iter, void_t result);
C_API void thrd_destroy(future_t *);

#define atomic_lock(mutex) c89atomic_spinlock_lock((atomic_spinlock *)mutex)
#define atomic_unlock(mutex) c89atomic_spinlock_unlock((atomic_spinlock *)mutex)
C_API bool thrd_is_finish(future_t *);

/**
* `Release/free` allocated memory, must be called if not using `get_args()` function.
Expand Down
1 change: 1 addition & 0 deletions src/except.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ EX_EXCEPTION(invalid_type);
EX_EXCEPTION(range_error);
EX_EXCEPTION(divide_by_zero);
EX_EXCEPTION(logic_error);
EX_EXCEPTION(future_error);
EX_EXCEPTION(system_error);
EX_EXCEPTION(domain_error);
EX_EXCEPTION(length_error);
Expand Down
54 changes: 40 additions & 14 deletions src/future.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,13 @@ static int raii_wrapper(void_t arg) {
}

static void thrd_start(future *f, promise *value, void_t arg) {
future_arg *f_arg = try_malloc(sizeof(future_arg));
future_arg *f_arg = try_calloc(1, sizeof(future_arg));
f_arg->func = f->func;
f_arg->arg = arg;
f_arg->value = value;
f_arg->type = RAII_FUTURE_ARG;
int r = thrd_create(&f->thread, raii_wrapper, f_arg);
if (thrd_create(&f->thread, raii_wrapper, f_arg) != thrd_success)
throw(future_error);
}

future *thrd_async(thrd_func_t fn, void_t args) {
Expand Down Expand Up @@ -120,27 +121,46 @@ RAII_INLINE uintptr_t thrd_self(void) {
}

future_t *thrd_for(thrd_func_t fn, size_t times, const char *desc, ...) {
future_t *pool = (future_t *)calloc_default(1, sizeof(future_t));
pool->futures = (future **)calloc_default(times, sizeof(pool->futures[0]) * 2);
args_t params;
unique_t *scope = unique_init();
future_t *pool = (future_t *)calloc_full(scope, 1, sizeof(future_t), RAII_FREE);
future **futures = (future **)calloc_default(times, sizeof(futures[0]) * 2);
va_list args;
args_t params;
size_t i;

va_start(args, desc);
params = raii_args_ex(nullptr, desc, args);
params->defer_set = true;
va_end(args);

scope->arena = pool;
pool->scope = scope;
raii_deferred(scope, (func_t)args_free, params);

for (i = 0; i < times; i++) {
va_start(args, desc);
params = raii_args_ex(nullptr, desc, args);
pool->futures[i] = thrd_async(fn, (void_t)params);
promise *p = promise_create();
future *f = future_create(fn);
future_arg *f_arg = try_calloc(1, sizeof(future_arg));
f_arg->func = f->func;
f_arg->arg = params;
f_arg->value = p;
f_arg->type = RAII_FUTURE_ARG;
f->value = p;
if (thrd_create(&f->thread, raii_wrapper, f_arg) != thrd_success)
throw(future_error);

futures[i] = f;
}
va_end(args);

pool->thread_count = times;
pool->futures = futures;
pool->type = RAII_POOL;
return pool;
}

thrd_values *thrd_sync(future_t *v) {
thrd_values_t *thrd_sync(future_t *v) {
if (is_type(v, RAII_POOL)) {
thrd_values *summary = (thrd_values *)calloc_default(v->thread_count, sizeof(thrd_values));
thrd_values_t *summary = (thrd_values_t *)calloc_default(1, sizeof(thrd_values_t));
summary->values = (raii_values_t **)calloc_default(v->thread_count, sizeof(summary->values[0]) * 2);
size_t i;

Expand All @@ -158,14 +178,20 @@ thrd_values *thrd_sync(future_t *v) {
throw(logic_error);
}

values_type thrd_then(result_func_t callback, thrd_values *iter, void_t result) {
void thrd_then(result_func_t callback, thrd_values_t *iter, void_t result) {
size_t i, max = iter->value_count;

for (i = 0; i < max; i++)
result = callback(result, i, iter->values[i]->value);

iter->values[max]->value.object = result;
return iter->values[max]->value;
raii_deferred_clean();
}

void thrd_destroy(future_t *f) {
if (is_type(f, RAII_POOL)) {
f->type = -1;
raii_delete(f->scope);
}
}

RAII_INLINE bool thrd_is_finish(future_t *f) {
Expand Down
28 changes: 23 additions & 5 deletions src/raii.c
Original file line number Diff line number Diff line change
Expand Up @@ -592,9 +592,14 @@ RAII_INLINE values_type args_in(args_t params, size_t index) {
}

args_t raii_args_ex(memory_t *scope, const char *desc, va_list argp) {
size_t i, count = simd_strlen(desc);
args_t params = try_calloc(1, sizeof(args_t));
params->args = try_calloc(count, sizeof(raii_values_t));
size_t i, len, count = simd_strlen(desc);
args_t params = try_calloc(1, sizeof(struct args_s));
uintptr_t **a;
void_t p;
string s;
params->args_size = sizeof(raii_values_t);
params->args = try_calloc(count, params->args_size);
params->args_size = params->args_size * count;

for (i = 0; i < count; i++) {
switch (*desc++) {
Expand Down Expand Up @@ -624,7 +629,15 @@ args_t raii_args_ex(memory_t *scope, const char *desc, va_list argp) {
break;
case 's':
// string argument
params->args[i].value.char_ptr = (char *)va_arg(argp, char *);
s = (char *)va_arg(argp, char *);
len = simd_strlen(s);
if (len > sizeof(raii_values_t)) {
params->args_size += len + 1;
params->args = try_realloc(params->args, params->args_size);
strncpy(params->args[i].value.char_ptr, s, len);
} else {
params->args[i].value.char_ptr = s;
}
break;
case 'a':
// array argument
Expand All @@ -640,8 +653,13 @@ args_t raii_args_ex(memory_t *scope, const char *desc, va_list argp) {
break;
case 'p':
// void pointer (any arbitrary pointer) argument
default:
params->args[i].value.object = va_arg(argp, void *);
default:
p = va_arg(argp, void *);
len = sizeof(p);
params->args_size += len;
params->args = try_realloc(params->args, params->args_size);
memcpy(params->args[i].value.object, p, sizeof(p));
break;
}
}
Expand Down

0 comments on commit a033f27

Please sign in to comment.