mirror of
https://github.com/janet-lang/janet
synced 2024-12-27 17:00:27 +00:00
Begin work on channels.
This commit is contained in:
parent
0403e306ed
commit
2eb2dddb59
@ -326,6 +326,72 @@ void janet_addtimeout(double sec) {
|
||||
add_timeout(to);
|
||||
}
|
||||
|
||||
/* Channels */
|
||||
|
||||
typedef struct {
|
||||
int32_t capacity;
|
||||
int32_t head;
|
||||
int32_t tail;
|
||||
JanetFiber **fibers;
|
||||
} JanetFiberQueue;
|
||||
|
||||
#define JANET_MAX_FQ_CAPACITY 0xFFFFFF
|
||||
|
||||
static void janet_fq_init(JanetFiberQueue *fq) {
|
||||
fq->fibers = NULL;
|
||||
fq->head = 0;
|
||||
fq->tail = 0;
|
||||
fq->capacity = 0;
|
||||
}
|
||||
|
||||
static int32_t janet_fq_count(JanetFiberQueue *fq) {
|
||||
return (fq->head > fq->tail)
|
||||
? (fq->tail + fq->capacity - fq->head)
|
||||
: (fq->tail - fq->head);
|
||||
}
|
||||
|
||||
static int janet_fq_push(JanetFiberQueue *fq, JanetFiber *fiber) {
|
||||
int32_t count = janet_fq_count(fq);
|
||||
if (count + 1 == JANET_MAX_FQ_CAPACITY) return 1;
|
||||
/* Resize if needed */
|
||||
if (count + 1 > fq->capacity) {
|
||||
int32_t newcap = (count + 1) * 2;
|
||||
if (newcap > JANET_MAX_FQ_CAPACITY) newcap = JANET_MAX_FQ_CAPACITY;
|
||||
if (fq->head > fq->tail) {
|
||||
/* Two segments, we need to allocate and memcpy x2 */
|
||||
JanetFiber **newfibers = malloc(sizeof(JanetFiber *) * newcap);
|
||||
if (NULL == newfibers) {
|
||||
JANET_OUT_OF_MEMORY;
|
||||
}
|
||||
int32_t seg1 = fq->capacity - fq->head;
|
||||
int32_t seq2 = fq->tail;
|
||||
memcpy(newfibers, fq->fibers + fq->head, seg1 * sizeof(JanetFiber *));
|
||||
memcpy(newfibers + seg1, fq->fibers, seq2 * sizeof(JanetFiber *));
|
||||
free(fq->fibers);
|
||||
fq->fibers = newfibers;
|
||||
fq->head = 0;
|
||||
fq->tail = count;
|
||||
} else {
|
||||
/* One segment, we can just realloc */
|
||||
fq->fibers = realloc(fq->fibers, sizeof(JanetFiber *) * newcap);
|
||||
if (NULL == fq->fibers) {
|
||||
JANET_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
fq->capacity = newcap;
|
||||
}
|
||||
fq->fibers[fq->tail++] = fiber;
|
||||
if (fq->tail >= fq->capacity) fq->tail = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int janet_fq_pop(JanetFiberQueue *fq, JanetFiber **out) {
|
||||
if (fq->head == fq->tail) return 1;
|
||||
*out = fq->fibers[fq->head++];
|
||||
if (fq->head >= fq->capacity) fq->head = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Main event loop */
|
||||
|
||||
void janet_loop1_impl(void);
|
||||
|
Loading…
Reference in New Issue
Block a user