Skip to content

Commit

Permalink
Merge pull request #242 from IdWV/global-variables
Browse files Browse the repository at this point in the history
Removed all global variables from libucode for thread safety
  • Loading branch information
jow- authored Dec 2, 2024
2 parents b0b5d93 + f9d2faf commit b324ad6
Show file tree
Hide file tree
Showing 5 changed files with 192 additions and 51 deletions.
20 changes: 15 additions & 5 deletions include/ucode/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,11 +206,6 @@ typedef struct {

uc_declare_vector(uc_resource_types_t, uc_resource_type_t *);


/* Object iteration */

extern uc_list_t uc_object_iterators;

typedef struct {
uc_list_t list;
struct lh_table *table;
Expand Down Expand Up @@ -270,6 +265,19 @@ uc_search_path_free(uc_search_path_t *search_path) {
}


/* TLS data */

typedef struct {
/* VM owning installed signal handlers */
uc_vm_t *signal_handler_vm;

/* Object iteration */
uc_list_t object_iterators;
} uc_thread_context_t;

__hidden uc_thread_context_t *uc_thread_context_get(void);


/* VM definitions */

typedef enum {
Expand Down Expand Up @@ -388,6 +396,7 @@ uc_value_t *ucv_array_push(uc_value_t *, uc_value_t *);
uc_value_t *ucv_array_shift(uc_value_t *);
uc_value_t *ucv_array_unshift(uc_value_t *, uc_value_t *);
void ucv_array_sort(uc_value_t *, int (*)(const void *, const void *));
void ucv_array_sort_r(uc_value_t *, int (*)(uc_value_t *, uc_value_t *, void *), void *);
bool ucv_array_delete(uc_value_t *, size_t, size_t);
bool ucv_array_set(uc_value_t *, size_t, uc_value_t *);
size_t ucv_array_length(uc_value_t *);
Expand All @@ -396,6 +405,7 @@ uc_value_t *ucv_object_new(uc_vm_t *);
uc_value_t *ucv_object_get(uc_value_t *, const char *, bool *);
bool ucv_object_add(uc_value_t *, const char *, uc_value_t *);
void ucv_object_sort(uc_value_t *, int (*)(const void *, const void *));
void ucv_object_sort_r(uc_value_t *, int (*)(const char *, uc_value_t *, const char *, uc_value_t *, void *), void *);
bool ucv_object_delete(uc_value_t *, const char *);
size_t ucv_object_length(uc_value_t *);

Expand Down
28 changes: 28 additions & 0 deletions include/ucode/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -267,4 +267,32 @@ uc_vector_extend_(char **base, size_t itemsize, size_t count, size_t add)
iter != NULL && iter >= (vec)->entries; \
iter--)

#ifdef __APPLE__

# define uc_vector_sort_cb(fn_, optype_, udtype_, ...) \
int fn_(void *ud, const void *k1, const void *k2) { \
optype_ v1 = *(optype_ *)k1; \
optype_ v2 = *(optype_ *)k2; \
udtype_ ctx = (udtype_)ud; \
__VA_ARGS__ \
}

# define uc_vector_sort(v_, cmp_, ud_) \
qsort_r((v_)->entries, (v_)->count, sizeof((v_)->entries[0]), ud_, cmp_)

#else

# define uc_vector_sort_cb(fn_, optype_, udtype_, ...) \
int fn_(const void *k1, const void *k2, void *ud) { \
optype_ v1 = *(optype_ *)k1; \
optype_ v2 = *(optype_ *)k2; \
udtype_ ctx = (udtype_)ud; \
__VA_ARGS__ \
}

# define uc_vector_sort(v_, cmp_, ud_) \
qsort_r((v_)->entries, (v_)->count, sizeof((v_)->entries[0]), cmp_, ud_)

#endif

#endif /* UCODE_UTIL_H */
50 changes: 25 additions & 25 deletions tests/custom/03_stdlib/60_gc
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@ Returns an object count if the given operation is `count`.
-- End --

-- Expect stdout --
Count #1: 6
Count #2: 7
Count #3: 6
Count #4: 7
Count #5: 6
Count #1: 5
Count #2: 6
Count #3: 5
Count #4: 6
Count #5: 5
-- End --


Expand Down Expand Up @@ -84,24 +84,24 @@ Testing enabling the automatic collector.
-- End --

-- Expect stdout --
Count #1: 7
Count #2: 14
Count #3: 14
Count #4: 14
Count #5: 14
Count #6: 14
Count #7: 14
Count #8: 14
Count #9: 14
Count #10: 14
Count #11: 14
Count #12: 24
Count #13: 34
Count #14: 44
Count #15: 54
Count #16: 64
Count #17: 74
Count #18: 84
Count #19: 94
Count #20: 104
Count #1: 6
Count #2: 12
Count #3: 12
Count #4: 12
Count #5: 12
Count #6: 12
Count #7: 12
Count #8: 12
Count #9: 12
Count #10: 12
Count #11: 12
Count #12: 22
Count #13: 32
Count #14: 42
Count #15: 52
Count #16: 62
Count #17: 72
Count #18: 82
Count #19: 92
Count #20: 102
-- End --
95 changes: 84 additions & 11 deletions types.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,6 @@
#include "ucode/vm.h"
#include "ucode/program.h"

uc_list_t uc_object_iterators = {
.prev = &uc_object_iterators,
.next = &uc_object_iterators
};

static char *uc_default_search_path[] = { LIB_SEARCH_PATH };

uc_parse_config_t uc_default_parse_config = {
Expand Down Expand Up @@ -785,6 +780,28 @@ ucv_array_unshift(uc_value_t *uv, uc_value_t *item)
return item;
}

typedef struct {
int (*cmp)(uc_value_t *, uc_value_t *, void *);
void *ud;
} array_sort_ctx_t;

static uc_vector_sort_cb(ucv_array_sort_r_cb, uc_value_t *, array_sort_ctx_t *, {
return ctx->cmp(v1, v2, ctx->ud);
});

void
ucv_array_sort_r(uc_value_t *uv,
int (*cmp)(uc_value_t *, uc_value_t *, void *), void *ud)
{
array_sort_ctx_t ctx = { .cmp = cmp, .ud = ud };
uc_array_t *array = (uc_array_t *)uv;

if (ucv_type(uv) != UC_ARRAY || array->count <= 1)
return;

uc_vector_sort(array, ucv_array_sort_r_cb, &ctx);
}

void
ucv_array_sort(uc_value_t *uv, int (*cmp)(const void *, const void *))
{
Expand Down Expand Up @@ -876,7 +893,7 @@ ucv_array_length(uc_value_t *uv)
static void
ucv_free_object_entry(struct lh_entry *entry)
{
uc_list_foreach(item, &uc_object_iterators) {
uc_list_foreach(item, &uc_thread_context_get()->object_iterators) {
uc_object_iterator_t *iter = (uc_object_iterator_t *)item;

if (iter->u.pos == entry)
Expand Down Expand Up @@ -933,7 +950,7 @@ ucv_object_add(uc_value_t *uv, const char *key, uc_value_t *val)

/* insert will rehash table, backup affected iterator states */
if (rehash) {
uc_list_foreach(item, &uc_object_iterators) {
uc_list_foreach(item, &uc_thread_context_get()->object_iterators) {
uc_object_iterator_t *iter = (uc_object_iterator_t *)item;

if (iter->table != object->table)
Expand All @@ -957,7 +974,7 @@ ucv_object_add(uc_value_t *uv, const char *key, uc_value_t *val)

/* restore affected iterator state pointer after rehash */
if (rehash) {
uc_list_foreach(item, &uc_object_iterators) {
uc_list_foreach(item, &uc_thread_context_get()->object_iterators) {
uc_object_iterator_t *iter = (uc_object_iterator_t *)item;

if (iter->table != object->table)
Expand Down Expand Up @@ -985,8 +1002,29 @@ ucv_object_add(uc_value_t *uv, const char *key, uc_value_t *val)
return true;
}

void
ucv_object_sort(uc_value_t *uv, int (*cmp)(const void *, const void *))

typedef struct {
int (*cmp)(const void *, const void *);
int (*cmpr)(const char *, uc_value_t *, const char *, uc_value_t *, void *);
void *ud;
} object_sort_ctx_t;

static uc_vector_sort_cb(ucv_object_sort_cb, const void *, object_sort_ctx_t *, {
(void)v1;
(void)v2;

return ctx->cmp(k1, k2);
});

static uc_vector_sort_cb(ucv_object_sort_r_cb, const struct lh_entry *, object_sort_ctx_t *, {
return ctx->cmpr(
v1 ? lh_entry_k(v1) : NULL, v1 ? lh_entry_v(v1) : NULL,
v2 ? lh_entry_k(v2) : NULL, v2 ? lh_entry_v(v2) : NULL,
ctx->ud);
});

static void
ucv_object_sort_common(uc_value_t *uv, object_sort_ctx_t *ctx)
{
uc_object_t *object = (uc_object_t *)uv;
struct lh_table *t;
Expand All @@ -1007,7 +1045,8 @@ ucv_object_sort(uc_value_t *uv, int (*cmp)(const void *, const void *))
if (!keys.entries)
return;

qsort(keys.entries, keys.count, sizeof(keys.entries[0]), cmp);
uc_vector_sort(&keys,
ctx->cmpr ? ucv_object_sort_r_cb : ucv_object_sort_cb, ctx);

for (i = 0; i < keys.count; i++) {
e = keys.entries[i];
Expand All @@ -1027,6 +1066,25 @@ ucv_object_sort(uc_value_t *uv, int (*cmp)(const void *, const void *))
uc_vector_clear(&keys);
}

void
ucv_object_sort_r(uc_value_t *uv,
int (*cmp)(const char *, uc_value_t *,
const char *, uc_value_t *, void *),
void *ud)
{
object_sort_ctx_t ctx = { .cmp = NULL, .cmpr = cmp, .ud = ud };

ucv_object_sort_common(uv, &ctx);
}

void
ucv_object_sort(uc_value_t *uv, int (*cmp)(const void *, const void *))
{
object_sort_ctx_t ctx = { .cmp = cmp, .cmpr = NULL, .ud = NULL };

ucv_object_sort_common(uv, &ctx);
}

bool
ucv_object_delete(uc_value_t *uv, const char *key)
{
Expand Down Expand Up @@ -2418,3 +2476,18 @@ uc_search_path_init(uc_search_path_t *search_path)
for (i = 0; i < ARRAY_SIZE(uc_default_search_path); i++)
uc_vector_push(search_path, xstrdup(uc_default_search_path[i]));
}


static __thread uc_thread_context_t *tls_ctx;

uc_thread_context_t *
uc_thread_context_get(void)
{
if (tls_ctx == NULL) {
tls_ctx = xalloc(sizeof(*tls_ctx));
tls_ctx->object_iterators.prev = &tls_ctx->object_iterators;
tls_ctx->object_iterators.next = &tls_ctx->object_iterators;
}

return tls_ctx;
}
Loading

0 comments on commit b324ad6

Please sign in to comment.