Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core: refactor timers #492

Merged
merged 1 commit into from
Apr 17, 2024
Merged
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
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ add_executable(tjs
src/ffi.c
src/fs.c
src/fswatch.c
src/mem.c
src/modules.c
src/os.c
src/process.c
Expand Down
27 changes: 27 additions & 0 deletions benchmark/million-timers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const NUM_TIMERS = 1_000_000;

let timerCalls = 0;
let timeout = 0;

function timerCb() {
timerCalls++;

if (timerCalls === NUM_TIMERS) {
performance.mark('end');

console.log(performance.measure('full', 'start', 'end'));
console.log(performance.measure('just-timers', 'end-start', 'end'));
}
}

performance.mark('start');

for (let i = 0; i < NUM_TIMERS; i++) {
if (i % 1000 === 0) {
timeout++;
}

setTimeout(timerCb, timeout);
}

performance.mark('end-start');
108,605 changes: 54,247 additions & 54,358 deletions src/bundles/c/core/polyfills.c

Large diffs are not rendered by default.

42 changes: 42 additions & 0 deletions src/hash.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* txiki.js
*
* Copyright (c) 2024-present Saúl Ibarra Corretgé <s@saghul.net>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#ifndef TJS_HASH_H
#define TJS_HASH_H

#include "mem.h"

#include <stdint.h>

#define uthash_malloc(sz) tjs__malloc(sz)
#define uthash_free(ptr,sz) tjs__free(ptr)

#include "uthash.h"

#define HASH_FIND_INT64(head,findint,out) \
HASH_FIND(hh,head,findint,sizeof(int64_t),out)
#define HASH_ADD_INT64(head,intfield,add) \
HASH_ADD(hh,head,intfield,sizeof(int64_t),add)

#endif
62 changes: 4 additions & 58 deletions src/js/polyfills/timers.js
Original file line number Diff line number Diff line change
@@ -1,61 +1,7 @@
const core = globalThis[Symbol.for('tjs.internal.core')];

const timers = new Map();
let nextId = 1;
globalThis.setTimeout = core.setTimeout;
globalThis.clearTimeout = core.clearTimeout;

function getNextId() {
let id;

// eslint-disable-next-line no-constant-condition
while (true) {
id = nextId++;

if (!timers.has(id)) {
break;
}

if (nextId >= Number.MAX_SAFE_INTEGER) {
nextId = 1;
}
}

return id;
}

globalThis.setTimeout = (fn, ms, ...args) => {
const timer = core.setTimeout(fn, ms, ...args);
const id = getNextId();

timers.set(id, timer);

return id;
};

globalThis.clearTimeout = id => {
const timer = timers.get(id);

if (timer) {
core.clearTimeout(timer);
}

timers.delete(id);
};

globalThis.setInterval = (fn, ms, ...args) => {
const timer = core.setInterval(fn, ms, ...args);
const id = getNextId();

timers.set(id, timer);

return id;
};

globalThis.clearInterval = id => {
const timer = timers.get(id);

if (timer) {
core.clearInterval(timer);
}

timers.delete(id);
};
globalThis.setInterval = core.setInterval;
globalThis.clearInterval = core.setInterval;
72 changes: 72 additions & 0 deletions src/mem.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* txiki.js
*
* Copyright (c) 2024-present Saúl Ibarra Corretgé <s@saghul.net>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#include "../deps/quickjs/cutils.h"
#include "mem.h"

#include <stdlib.h>

#ifdef TJS__HAS_MIMALLOC
#include <mimalloc.h>
#endif

size_t tjs__malloc_usable_size(const void *ptr) {
#if defined(TJS__HAS_MIMALLOC)
return mi_malloc_usable_size(ptr);
#else
return js__malloc_usable_size(ptr):
#endif
}

void *tjs__malloc(size_t size) {
#ifdef TJS__HAS_MIMALLOC
return mi_malloc(size);
#else
return malloc(size);
#endif
}

void *tjs__calloc(size_t count, size_t size) {
#ifdef TJS__HAS_MIMALLOC
return mi_calloc(count, size);
#else
return calloc(count, size);
#endif
}

void tjs__free(void *ptr) {
#ifdef TJS__HAS_MIMALLOC
mi_free(ptr);
#else
free(ptr);
#endif
}

void *tjs__realloc(void *ptr, size_t size) {
#ifdef TJS__HAS_MIMALLOC
return mi_realloc(ptr, size);
#else
return realloc(ptr, size);
#endif
}
36 changes: 36 additions & 0 deletions src/mem.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* txiki.js
*
* Copyright (c) 2024-present Saúl Ibarra Corretgé <s@saghul.net>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#ifndef TJS_MEM_H
#define TJS_MEM_H

#include <stdlib.h>

size_t tjs__malloc_usable_size(const void *ptr);
void *tjs__malloc(size_t size);
void *tjs__calloc(size_t count, size_t size);
void tjs__free(void *ptr);
void *tjs__realloc(void *ptr, size_t size);

#endif
7 changes: 7 additions & 0 deletions src/private.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <stdbool.h>
#include <uv.h>

typedef struct TJSTimer TJSTimer;

struct TJSRuntime {
TJSRunOptions options;
Expand All @@ -54,6 +55,10 @@ struct TJSRuntime {
struct {
IM3Environment env;
} wasm_ctx;
struct {
TJSTimer *timers;
int64_t next_timer;
} timers;
};

void tjs__mod_dns_init(JSContext *ctx, JSValue ns);
Expand Down Expand Up @@ -96,6 +101,8 @@ JSValue tjs__get_args(JSContext *ctx);

int tjs__eval_bytecode(JSContext *ctx, const uint8_t *buf, size_t buf_len);

void tjs__destroy_timers(TJSRuntime *qrt);

uv_loop_t *TJS_GetLoop(TJSRuntime *qrt);
TJSRuntime *TJS_NewRuntimeWorker(void);
TJSRuntime *TJS_NewRuntimeInternal(bool is_worker, TJSRunOptions *options);
Expand Down
Loading
Loading