aboutsummaryrefslogtreecommitdiff
path: root/stdlib
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib')
-rw-r--r--stdlib/README.md1
-rw-r--r--stdlib/channels.c157
-rw-r--r--stdlib/channels.h45
-rw-r--r--stdlib/datatypes.h7
-rw-r--r--stdlib/enums.c1
-rw-r--r--stdlib/metamethods.c1
-rw-r--r--stdlib/stdlib.c30
-rw-r--r--stdlib/stdlib.h2
-rw-r--r--stdlib/structs.c1
-rw-r--r--stdlib/tomo.h1
-rw-r--r--stdlib/types.h4
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;