Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,18 @@ jobs:
- name: test
run: |
make -j$(getconf _NPROCESSORS_ONLN) CONFIG_WERROR=y CONFIG_UBSAN=y test

windows:
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- name: build
run: |
make CONFIG_WIN32=y CONFIG_WERROR=y
- name: stats
run: |
make CONFIG_WIN32=y CONFIG_WERROR=y qjs
./qjs.exe -qd
- name: test
run: |
make CONFIG_WIN32=y CONFIG_WERROR=y test
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ DEFINES+=-D__USE_MINGW_ANSI_STDIO # for standard snprintf behavior
endif

CFLAGS+=$(DEFINES)
CFLAGS+=-std=c11
CFLAGS_DEBUG=$(CFLAGS) -O0
CFLAGS_SMALL=$(CFLAGS) -Os
CFLAGS_OPT=$(CFLAGS) -O2
Expand Down Expand Up @@ -189,10 +190,10 @@ QJS_LIB_OBJS+=$(OBJDIR)/libbf.o
QJS_OBJS+=$(OBJDIR)/qjscalc.o
endif

HOST_LIBS=-lm -ldl -lpthread
HOST_LIBS=-lm -ldl
LIBS=-lm
ifndef CONFIG_WIN32
LIBS+=-ldl -lpthread
LIBS+=-ldl
endif
LIBS+=$(EXTRA_LIBS)

Expand Down
1 change: 0 additions & 1 deletion qjsc.c
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,6 @@ static int output_executable(const char *out_filename, const char *cfilename,
*arg++ = libjsname;
*arg++ = "-lm";
*arg++ = "-ldl";
*arg++ = "-lpthread";
*arg = NULL;

if (verbose) {
Expand Down
33 changes: 15 additions & 18 deletions quickjs-libc.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ typedef sig_t sighandler_t;
#endif

#ifdef USE_WORKER
#include <pthread.h>
#include <threads.h>
#include <stdatomic.h>
#endif

Expand Down Expand Up @@ -106,7 +106,7 @@ typedef struct {
typedef struct {
int ref_count;
#ifdef USE_WORKER
pthread_mutex_t mutex;
mtx_t mutex;
#endif
struct list_head msg_queue; /* list of JSWorkerMessage.link */
int read_fd;
Expand Down Expand Up @@ -2166,7 +2166,7 @@ static int handle_posted_message(JSRuntime *rt, JSContext *ctx,
JSWorkerMessage *msg;
JSValue obj, data_obj, func, retval;

pthread_mutex_lock(&ps->mutex);
mtx_lock(&ps->mutex);
if (!list_empty(&ps->msg_queue)) {
el = ps->msg_queue.next;
msg = list_entry(el, JSWorkerMessage, link);
Expand All @@ -2186,7 +2186,7 @@ static int handle_posted_message(JSRuntime *rt, JSContext *ctx,
}
}

pthread_mutex_unlock(&ps->mutex);
mtx_unlock(&ps->mutex);

data_obj = JS_ReadObject(ctx, msg->data, msg->data_len,
JS_READ_OBJ_SAB | JS_READ_OBJ_REFERENCE);
Expand Down Expand Up @@ -2216,7 +2216,7 @@ static int handle_posted_message(JSRuntime *rt, JSContext *ctx,
}
ret = 1;
} else {
pthread_mutex_unlock(&ps->mutex);
mtx_unlock(&ps->mutex);
ret = 0;
}
return ret;
Expand Down Expand Up @@ -3195,7 +3195,7 @@ static JSWorkerMessagePipe *js_new_message_pipe(void)
}
ps->ref_count = 1;
init_list_head(&ps->msg_queue);
pthread_mutex_init(&ps->mutex, NULL);
mtx_init(&ps->mutex, mtx_timed);
ps->read_fd = pipe_fds[0];
ps->write_fd = pipe_fds[1];
return ps;
Expand Down Expand Up @@ -3235,7 +3235,7 @@ static void js_free_message_pipe(JSWorkerMessagePipe *ps)
msg = list_entry(el, JSWorkerMessage, link);
js_free_message(msg);
}
pthread_mutex_destroy(&ps->mutex);
mtx_destroy(&ps->mutex);
close(ps->read_fd);
close(ps->write_fd);
free(ps);
Expand Down Expand Up @@ -3268,7 +3268,7 @@ static JSClassDef js_worker_class = {
.finalizer = js_worker_finalizer,
};

static void *worker_func(void *opaque)
static int worker_func(void *opaque)
{
WorkerFuncArgs *args = opaque;
JSRuntime *rt;
Expand Down Expand Up @@ -3311,7 +3311,7 @@ static void *worker_func(void *opaque)
JS_FreeContext(ctx);
js_std_free_handlers(rt);
JS_FreeRuntime(rt);
return NULL;
return 0;
}

static JSValue js_worker_ctor_internal(JSContext *ctx, JSValueConst new_target,
Expand Down Expand Up @@ -3351,8 +3351,7 @@ static JSValue js_worker_ctor(JSContext *ctx, JSValueConst new_target,
{
JSRuntime *rt = JS_GetRuntime(ctx);
WorkerFuncArgs *args = NULL;
pthread_t tid;
pthread_attr_t attr;
thrd_t tid;
JSValue obj = JS_UNDEFINED;
int ret;
const char *filename = NULL, *basename;
Expand Down Expand Up @@ -3399,15 +3398,13 @@ static JSValue js_worker_ctor(JSContext *ctx, JSValueConst new_target,
if (JS_IsException(obj))
goto fail;

pthread_attr_init(&attr);
/* no join at the end */
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
ret = pthread_create(&tid, &attr, worker_func, args);
pthread_attr_destroy(&attr);
if (ret != 0) {
ret = thrd_create(&tid, worker_func, args);
if (ret != thrd_success) {
JS_ThrowTypeError(ctx, "could not create worker");
goto fail;
}
thrd_detach(tid);
JS_FreeCString(ctx, basename);
JS_FreeCString(ctx, filename);
return obj;
Expand Down Expand Up @@ -3475,7 +3472,7 @@ static JSValue js_worker_postMessage(JSContext *ctx, JSValueConst this_val,
}

ps = worker->send_pipe;
pthread_mutex_lock(&ps->mutex);
mtx_lock(&ps->mutex);
/* indicate that data is present */
if (list_empty(&ps->msg_queue)) {
uint8_t ch = '\0';
Expand All @@ -3489,7 +3486,7 @@ static JSValue js_worker_postMessage(JSContext *ctx, JSValueConst this_val,
}
}
list_add_tail(&msg->link, &ps->msg_queue);
pthread_mutex_unlock(&ps->mutex);
mtx_unlock(&ps->mutex);
return JS_UNDEFINED;
fail:
if (msg) {
Expand Down
45 changes: 29 additions & 16 deletions quickjs.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@
#define CONFIG_PRINTF_RNDN
#endif

/* define to include Atomics.* operations which depend on the OS
threads */
#if !defined(EMSCRIPTEN)
#define CONFIG_ATOMICS
#endif

#if !defined(EMSCRIPTEN)
/* enable stack limitation */
#define CONFIG_STACK_CHECK
Expand Down Expand Up @@ -104,7 +110,7 @@
//#define FORCE_GC_AT_MALLOC

#ifdef CONFIG_ATOMICS
#include <pthread.h>
#include <threads.h>
#include <stdatomic.h>
#include <errno.h>
#endif
Expand Down Expand Up @@ -53932,14 +53938,21 @@ static JSValue js_atomics_isLockFree(JSContext *ctx,
typedef struct JSAtomicsWaiter {
struct list_head link;
BOOL linked;
pthread_cond_t cond;
cnd_t cond;
int32_t *ptr;
} JSAtomicsWaiter;

static pthread_mutex_t js_atomics_mutex = PTHREAD_MUTEX_INITIALIZER;
static once_flag js_atomics_mutex_init_flag = ONCE_FLAG_INIT;
static mtx_t js_atomics_mutex;
static struct list_head js_atomics_waiter_list =
LIST_HEAD_INIT(js_atomics_waiter_list);

static void js_atomics_mutex_init(void)
{
if (mtx_init(&js_atomics_mutex, mtx_timed))
abort();
}

static JSValue js_atomics_wait(JSContext *ctx,
JSValueConst this_obj,
int argc, JSValueConst *argv)
Expand Down Expand Up @@ -53981,43 +53994,42 @@ static JSValue js_atomics_wait(JSContext *ctx,

/* XXX: inefficient if large number of waiters, should hash on
'ptr' value */
/* XXX: use Linux futexes when available ? */
pthread_mutex_lock(&js_atomics_mutex);
call_once(&js_atomics_mutex_init_flag, js_atomics_mutex_init);
mtx_lock(&js_atomics_mutex);
if (size_log2 == 3) {
res = *(int64_t *)ptr != v;
} else {
res = *(int32_t *)ptr != v;
}
if (res) {
pthread_mutex_unlock(&js_atomics_mutex);
mtx_unlock(&js_atomics_mutex);
return JS_AtomToString(ctx, JS_ATOM_not_equal);
}

waiter = &waiter_s;
waiter->ptr = ptr;
pthread_cond_init(&waiter->cond, NULL);
cnd_init(&waiter->cond);
waiter->linked = TRUE;
list_add_tail(&waiter->link, &js_atomics_waiter_list);

if (timeout == INT64_MAX) {
pthread_cond_wait(&waiter->cond, &js_atomics_mutex);
cnd_wait(&waiter->cond, &js_atomics_mutex);
ret = 0;
} else {
/* XXX: use clock monotonic */
clock_gettime(CLOCK_REALTIME, &ts);
timespec_get(&ts, TIME_UTC);
ts.tv_sec += timeout / 1000;
ts.tv_nsec += (timeout % 1000) * 1000000;
if (ts.tv_nsec >= 1000000000) {
ts.tv_nsec -= 1000000000;
ts.tv_sec++;
}
ret = pthread_cond_timedwait(&waiter->cond, &js_atomics_mutex,
&ts);
ret = cnd_timedwait(&waiter->cond, &js_atomics_mutex, &ts);
}
if (waiter->linked)
list_del(&waiter->link);
pthread_mutex_unlock(&js_atomics_mutex);
pthread_cond_destroy(&waiter->cond);
mtx_unlock(&js_atomics_mutex);
cnd_destroy(&waiter->cond);
if (ret == ETIMEDOUT) {
return JS_AtomToString(ctx, JS_ATOM_timed_out);
} else {
Expand Down Expand Up @@ -54050,7 +54062,8 @@ static JSValue js_atomics_notify(JSContext *ctx,

n = 0;
if (abuf->shared && count > 0) {
pthread_mutex_lock(&js_atomics_mutex);
call_once(&js_atomics_mutex_init_flag, js_atomics_mutex_init);
mtx_lock(&js_atomics_mutex);
init_list_head(&waiter_list);
list_for_each_safe(el, el1, &js_atomics_waiter_list) {
waiter = list_entry(el, JSAtomicsWaiter, link);
Expand All @@ -54065,9 +54078,9 @@ static JSValue js_atomics_notify(JSContext *ctx,
}
list_for_each(el, &waiter_list) {
waiter = list_entry(el, JSAtomicsWaiter, link);
pthread_cond_signal(&waiter->cond);
cnd_signal(&waiter->cond);
}
pthread_mutex_unlock(&js_atomics_mutex);
mtx_unlock(&js_atomics_mutex);
}
return JS_NewInt32(ctx, n);
}
Expand Down
4 changes: 0 additions & 4 deletions release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ if echo $release_list | grep -w -q win_binary ; then

# win64

dlldir=/usr/x86_64-w64-mingw32/sys-root/mingw/bin
cross_prefix="x86_64-w64-mingw32-"
d="quickjs-win-x86_64-${version}"
outdir="/tmp/${d}"
Expand All @@ -56,15 +55,13 @@ mkdir -p $outdir
make CONFIG_WIN32=y qjs.exe
cp qjs.exe $outdir
${cross_prefix}strip $outdir/qjs.exe
cp $dlldir/libwinpthread-1.dll $outdir

( cd /tmp/$d && rm -f ../${d}.zip && zip -r ../${d}.zip . )

make CONFIG_WIN32=y clean

# win32

dlldir=/usr/i686-w64-mingw32/sys-root/mingw/bin
cross_prefix="i686-w64-mingw32-"
d="quickjs-win-i686-${version}"
outdir="/tmp/${d}"
Expand All @@ -78,7 +75,6 @@ make CONFIG_WIN32=y clean
make CONFIG_WIN32=y CONFIG_M32=y qjs.exe
cp qjs.exe $outdir
${cross_prefix}strip $outdir/qjs.exe
cp $dlldir/libwinpthread-1.dll $outdir

( cd /tmp/$d && rm -f ../${d}.zip && zip -r ../${d}.zip . )

Expand Down
Loading