diff options
Diffstat (limited to 'stdlib')
| -rw-r--r-- | stdlib/README.md | 1 | ||||
| -rw-r--r-- | stdlib/channels.c | 157 | ||||
| -rw-r--r-- | stdlib/channels.h | 45 | ||||
| -rw-r--r-- | stdlib/datatypes.h | 7 | ||||
| -rw-r--r-- | stdlib/enums.c | 1 | ||||
| -rw-r--r-- | stdlib/metamethods.c | 1 | ||||
| -rw-r--r-- | stdlib/stdlib.c | 30 | ||||
| -rw-r--r-- | stdlib/stdlib.h | 2 | ||||
| -rw-r--r-- | stdlib/structs.c | 1 | ||||
| -rw-r--r-- | stdlib/tomo.h | 1 | ||||
| -rw-r--r-- | stdlib/types.h | 4 |
11 files changed, 34 insertions, 216 deletions
diff --git a/stdlib/README.md b/stdlib/README.md index 0d5b0819..9916c064 100644 --- a/stdlib/README.md +++ b/stdlib/README.md @@ -19,7 +19,6 @@ some common functionality. - Arrays: [header](stdlib/arrays.h), [implementation](stdlib/arrays.c) - Bools: [header](stdlib/bools.h), [implementation](stdlib/bools.c) - Bytes: [header](stdlib/bytes.h), [implementation](stdlib/bytes.c) -- Channels: [header](stdlib/channels.h), [implementation](stdlib/channels.c) - C Strings: [header](stdlib/c_strings.h), [implementation](stdlib/c_strings.c) - Files (used internally only): [header](stdlib/files.h), [implementation](stdlib/files.c) - Functiontype: [header](stdlib/functiontype.h), [implementation](stdlib/functiontype.c) diff --git a/stdlib/channels.c b/stdlib/channels.c deleted file mode 100644 index ee7ebde2..00000000 --- a/stdlib/channels.c +++ /dev/null @@ -1,157 +0,0 @@ -// Functions that operate on channels - -#include <ctype.h> -#include <err.h> -#include <gc.h> -#include <math.h> -#include <stdbool.h> -#include <stdint.h> -#include <stdlib.h> -#include <pthread.h> -#include <sys/param.h> - -#include "arrays.h" -#include "metamethods.h" -#include "integers.h" -#include "siphash.h" -#include "text.h" -#include "types.h" -#include "util.h" - -public Channel_t *Channel$new(Int_t max_size) -{ - if (Int$compare_value(max_size, I_small(0)) <= 0) - fail("Cannot create a channel with a size less than one: %ld", max_size); - Channel_t *channel = new(Channel_t); - channel->items = (Array_t){}; - channel->mutex = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER; - channel->cond = (pthread_cond_t)PTHREAD_COND_INITIALIZER; - channel->max_size = Int_to_Int64(max_size, false); - return channel; -} - -public void Channel$give(Channel_t *channel, const void *item, bool front, int64_t padded_item_size) -{ - (void)pthread_mutex_lock(&channel->mutex); - while (channel->items.length >= channel->max_size) - pthread_cond_wait(&channel->cond, &channel->mutex); - Int_t index = front ? I_small(1) : I_small(0); - Array$insert(&channel->items, item, index, padded_item_size); - (void)pthread_mutex_unlock(&channel->mutex); - (void)pthread_cond_signal(&channel->cond); -} - -public void Channel$give_all(Channel_t *channel, Array_t to_give, bool front, int64_t padded_item_size) -{ - if (to_give.length == 0) return; - (void)pthread_mutex_lock(&channel->mutex); - Int_t index = front ? I_small(1) : I_small(0); - if (channel->items.length + to_give.length >= channel->max_size) { - for (int64_t i = 0; i < to_give.length; i++) { - while (channel->items.length >= channel->max_size) - pthread_cond_wait(&channel->cond, &channel->mutex); - Array$insert(&channel->items, to_give.data + i*to_give.stride, index, padded_item_size); - } - } else { - Array$insert_all(&channel->items, to_give, index, padded_item_size); - } - (void)pthread_mutex_unlock(&channel->mutex); - (void)pthread_cond_signal(&channel->cond); -} - -public void Channel$get(Channel_t *channel, void *out, bool front, int64_t item_size, int64_t padded_item_size) -{ - (void)pthread_mutex_lock(&channel->mutex); - while (channel->items.length == 0) - pthread_cond_wait(&channel->cond, &channel->mutex); - memcpy(out, channel->items.data + channel->items.stride * (front ? 0 : channel->items.length-1), (size_t)(item_size)); - Int_t index = front ? I_small(1) : Int64_to_Int(channel->items.length); - Array$remove_at(&channel->items, index, I_small(1), padded_item_size); - (void)pthread_mutex_unlock(&channel->mutex); - (void)pthread_cond_signal(&channel->cond); -} - -public void Channel$peek(Channel_t *channel, void *out, bool front, int64_t item_size) -{ - (void)pthread_mutex_lock(&channel->mutex); - while (channel->items.length == 0) - pthread_cond_wait(&channel->cond, &channel->mutex); - int64_t index = front ? 0 : channel->items.length-1; - memcpy(out, channel->items.data + channel->items.stride*index, (size_t)(item_size)); - (void)pthread_mutex_unlock(&channel->mutex); - (void)pthread_cond_signal(&channel->cond); -} - -public Array_t Channel$view(Channel_t *channel) -{ - (void)pthread_mutex_lock(&channel->mutex); - ARRAY_INCREF(channel->items); - Array_t ret = channel->items; - (void)pthread_mutex_unlock(&channel->mutex); - return ret; -} - -public void Channel$clear(Channel_t *channel) -{ - (void)pthread_mutex_lock(&channel->mutex); - Array$clear(&channel->items); - (void)pthread_mutex_unlock(&channel->mutex); - (void)pthread_cond_signal(&channel->cond); -} - -PUREFUNC public uint64_t Channel$hash(const void *channel, const TypeInfo_t *type) -{ - (void)type; - return siphash24(*(void**)channel, sizeof(Channel_t*)); -} - -PUREFUNC public int32_t Channel$compare(const void *x, const void *y, const TypeInfo_t*) -{ - return (*(Channel_t**)x > *(Channel_t**)y) - (*(Channel_t**)x < *(Channel_t**)y); -} - -PUREFUNC public bool Channel$equal(const void *x, const void *y, const TypeInfo_t*) -{ - return (*(void**)x == *(void**)y); -} - -public Text_t Channel$as_text(const void *channel, bool colorize, const TypeInfo_t *type) -{ - const TypeInfo_t *item_type = type->ChannelInfo.item; - if (!channel) { - Text_t typename = generic_as_text(NULL, false, item_type); - return Text$concat(colorize ? Text("\x1b[34;1m|:") : Text("|:"), typename, colorize ? Text("|\x1b[m") : Text("|")); - } - Text_t typename = generic_as_text(NULL, false, item_type); - return Text$concat( - colorize ? Text("\x1b[34;1m|:") : Text("|:"), - typename, - Text("|<"), - Int64$hex(*(int64_t*)channel, I_small(0), true, true), - colorize ? Text(">\x1b[m") : Text(">") - ); -} - -public PUREFUNC bool Channel$is_none(const void *obj, const TypeInfo_t*) -{ - return *(void**)obj == NULL; -} - -public void Channel$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type) -{ - Channel_t *channel = (Channel_t*)obj; - Array$serialize(&channel->items, out, pointers, Array$info(type->ChannelInfo.item)); - Int64$serialize(&channel->max_size, out, pointers, &Int64$info); -} - -public void Channel$deserialize(FILE *in, void *outval, Array_t *pointers, const TypeInfo_t *type) -{ - Channel_t *channel = new(Channel_t); - channel->mutex = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER; - channel->cond = (pthread_cond_t)PTHREAD_COND_INITIALIZER; - Array$deserialize(in, &channel->items, pointers, Array$info(type->ChannelInfo.item)); - Int64$deserialize(in, &channel->max_size, pointers, &Int64$info); - *(Channel_t**)outval = channel; -} - -// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 diff --git a/stdlib/channels.h b/stdlib/channels.h deleted file mode 100644 index cd0a82f8..00000000 --- a/stdlib/channels.h +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once - -// Functions that operate on channels (thread-safe arrays) - -#include <stdbool.h> - -#include "datatypes.h" -#include "types.h" -#include "util.h" - -Channel_t *Channel$new(Int_t max_size); -void Channel$give(Channel_t *channel, const void *item, bool front, int64_t padded_item_size); -#define Channel$give_value(channel, item, front, padded_item_size) \ - ({ __typeof(item) _item = item; Channel$give(channel, &_item, front, padded_item_size); }) -void Channel$give_all(Channel_t *channel, Array_t to_give, bool front, int64_t padded_item_size); -void Channel$get(Channel_t *channel, void *out, bool front, int64_t item_size, int64_t padded_item_size); -#define Channel$get_value(channel, front, t, padded_item_size) \ - ({ t _val; Channel$get(channel, &_val, front, sizeof(t), padded_item_size); _val; }) -void Channel$peek(Channel_t *channel, void *out, bool front, int64_t item_size); -#define Channel$peek_value(channel, front, t) ({ t _val; Channel$peek(channel, &_val, front, sizeof(t)); _val; }) -void Channel$clear(Channel_t *channel); -Array_t Channel$view(Channel_t *channel); -PUREFUNC uint64_t Channel$hash(const void *channel, const TypeInfo_t *type); -PUREFUNC int32_t Channel$compare(const void *x, const void *y, const TypeInfo_t *type); -PUREFUNC bool Channel$equal(const void *x, const void *y, const TypeInfo_t *type); -Text_t Channel$as_text(const void *channel, bool colorize, const TypeInfo_t *type); -PUREFUNC bool Channel$is_none(const void *obj, const TypeInfo_t*); -void Channel$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t*); -void Channel$deserialize(FILE *in, void *outval, Array_t *pointers, const TypeInfo_t*); - -#define Channel$metamethods ((metamethods_t){ \ - .as_text=Channel$as_text, \ - .compare=Channel$compare, \ - .equal=Channel$equal, \ - .hash=Channel$hash, \ - .is_none=Channel$is_none, \ - .serialize=Channel$serialize, \ - .deserialize=Channel$deserialize, \ -}) - -#define Channel$info(item_info) &((TypeInfo_t){.size=sizeof(Channel_t), .align=__alignof__(Channel_t), \ - .tag=ChannelInfo, .ChannelInfo.item=item_info, \ - .metamethods=Channel$metamethods}) - -// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 diff --git a/stdlib/datatypes.h b/stdlib/datatypes.h index 31a99634..9c3cabc2 100644 --- a/stdlib/datatypes.h +++ b/stdlib/datatypes.h @@ -66,13 +66,6 @@ typedef struct Range_s { Int_t first, last, step; } Range_t; -typedef struct { - Array_t items; - pthread_mutex_t mutex; - pthread_cond_t cond; - int64_t max_size; -} Channel_t; - enum text_type { TEXT_SHORT_ASCII, TEXT_ASCII, TEXT_SHORT_GRAPHEMES, TEXT_GRAPHEMES, TEXT_SUBTEXT }; typedef struct Text_s { diff --git a/stdlib/enums.c b/stdlib/enums.c index b326e1ad..fb0b93a4 100644 --- a/stdlib/enums.c +++ b/stdlib/enums.c @@ -5,7 +5,6 @@ #include "arrays.h" #include "bools.h" -#include "channels.h" #include "functiontype.h" #include "integers.h" #include "metamethods.h" diff --git a/stdlib/metamethods.c b/stdlib/metamethods.c index 2871a965..c0e11cfc 100644 --- a/stdlib/metamethods.c +++ b/stdlib/metamethods.c @@ -6,7 +6,6 @@ #include "arrays.h" #include "bools.h" #include "bytes.h" -#include "channels.h" #include "functiontype.h" #include "integers.h" #include "metamethods.h" diff --git a/stdlib/stdlib.c b/stdlib/stdlib.c index cb9d2213..0266e788 100644 --- a/stdlib/stdlib.c +++ b/stdlib/stdlib.c @@ -621,4 +621,34 @@ public void sleep_num(double seconds) nanosleep(&ts, NULL); } +static void use_mutexed(Closure_t fn, void *userdata) +{ + void (*call)(void*, void*) = fn.fn; + struct data_t { + pthread_mutex_t mutex; + char item[0] __attribute__ ((aligned (8))); + }; + pthread_mutex_t *mutex = &((struct data_t*)userdata)->mutex; + pthread_mutex_lock(mutex); + void *mutexed_item = (void*)((struct data_t*)userdata)->item; + call(mutexed_item, fn.userdata); + pthread_mutex_unlock(mutex); +} + +public Closure_t _mutexed(const void *item, size_t size) +{ + struct data_t { + pthread_mutex_t mutex; + char item[size] __attribute__ ((aligned (8))); + }; + struct data_t *userdata = GC_MALLOC(sizeof(struct data_t)); + + pthread_mutex_init(&userdata->mutex, NULL); + memcpy(userdata->item, item, size); + return (Closure_t){ + .fn=(void*)use_mutexed, + .userdata=(void*)userdata, + }; +} + // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 diff --git a/stdlib/stdlib.h b/stdlib/stdlib.h index 7c9bd7e1..c68442a6 100644 --- a/stdlib/stdlib.h +++ b/stdlib/stdlib.h @@ -42,5 +42,7 @@ Closure_t spawn(Closure_t fn); bool pop_flag(char **argv, int *i, const char *flag, Text_t *result); void print_stack_trace(FILE *out, int start, int stop); void sleep_num(double seconds); +public Closure_t _mutexed(const void *item, size_t size); +#define mutexed(item) _mutexed((__typeof(item)[1]){item}, sizeof(item)) // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 diff --git a/stdlib/structs.c b/stdlib/structs.c index 1ff5a918..b3b26bde 100644 --- a/stdlib/structs.c +++ b/stdlib/structs.c @@ -5,7 +5,6 @@ #include "arrays.h" #include "bools.h" -#include "channels.h" #include "functiontype.h" #include "metamethods.h" #include "optionals.h" diff --git a/stdlib/tomo.h b/stdlib/tomo.h index 03257937..10ac3668 100644 --- a/stdlib/tomo.h +++ b/stdlib/tomo.h @@ -11,7 +11,6 @@ #include "bools.h" #include "bytes.h" #include "c_strings.h" -#include "channels.h" #include "datatypes.h" #include "enums.h" #include "functiontype.h" diff --git a/stdlib/types.h b/stdlib/types.h index f644390a..36508393 100644 --- a/stdlib/types.h +++ b/stdlib/types.h @@ -29,7 +29,7 @@ struct TypeInfo_s { int64_t size, align; metamethods_t metamethods; struct { // Anonymous tagged union for convenience - enum { OpaqueInfo, StructInfo, EnumInfo, PointerInfo, TextInfo, ArrayInfo, ChannelInfo, TableInfo, FunctionInfo, + enum { OpaqueInfo, StructInfo, EnumInfo, PointerInfo, TextInfo, ArrayInfo, TableInfo, FunctionInfo, OptionalInfo, TypeInfoInfo } tag; union { struct {} OpaqueInfo; @@ -42,7 +42,7 @@ struct TypeInfo_s { } TextInfo; struct { const TypeInfo_t *item; - } ArrayInfo, ChannelInfo; + } ArrayInfo; struct { const TypeInfo_t *key, *value; } TableInfo; |
