W6
This commit is contained in:
@@ -1,90 +0,0 @@
|
||||
#define NO_GLOBAL_ARENA_ALLOCATOR
|
||||
|
||||
struct MemoryArena {
|
||||
|
||||
u8* data;
|
||||
u64 size = 0;
|
||||
u64 capacity = 0;
|
||||
String name = "unnamed";
|
||||
|
||||
MemoryArena(u64 cap, String _name = "unnamed")
|
||||
{
|
||||
name = _name;
|
||||
capacity = cap;
|
||||
printf("(i) memory arena '%s' created with capacity of %llu bytes\n", name.c_str(), capacity);
|
||||
data = (u8*)malloc(cap);
|
||||
}
|
||||
|
||||
~MemoryArena()
|
||||
{
|
||||
free(data);
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
#ifdef DEBUG_MEMORY
|
||||
printf("(i) memory arena '%s' cleared after high mark of %llu bytes\n", name.c_str(), size);
|
||||
#endif
|
||||
size = 0;
|
||||
}
|
||||
|
||||
void* get(u64 size_needed)
|
||||
{
|
||||
u64 size_aligned = 8 + (8 * ((size_needed) / 8));
|
||||
u8* result = data + size;
|
||||
if(size_aligned + size >= capacity)
|
||||
{
|
||||
printf("(!) memory arena '%s' capacity (%llu) exceeded %llu/%llu + %llu >= %llu\n",
|
||||
name.c_str(), capacity, size_needed, size_aligned, size, capacity);
|
||||
return(0);
|
||||
}
|
||||
size += size_aligned;
|
||||
#ifdef DEBUG_MEMORY_DETAILED
|
||||
printf("(i) memory arena '%s' [+%llu]:%p alloc %llu/%llu bytes\n", name.c_str(), size, result, size_needed, size_aligned);
|
||||
#endif
|
||||
return(result);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
MemoryArena* current_memory_arena = 0;
|
||||
|
||||
void switch_to_system_alloc()
|
||||
{
|
||||
#ifdef GLOBAL_ARENA_ALLOCATOR
|
||||
current_memory_arena = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void switch_to_arena(MemoryArena* a)
|
||||
{
|
||||
#ifdef GLOBAL_ARENA_ALLOCATOR
|
||||
current_memory_arena = a;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef GLOBAL_ARENA_ALLOCATOR
|
||||
void * operator new(decltype(sizeof(0)) n) noexcept(false)
|
||||
{
|
||||
if(current_memory_arena)
|
||||
{
|
||||
return(current_memory_arena->get(n));
|
||||
}
|
||||
else
|
||||
{
|
||||
return(malloc(n));
|
||||
}
|
||||
}
|
||||
|
||||
void operator delete(void * p) throw()
|
||||
{
|
||||
if(current_memory_arena)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
free(p);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
+85
-7
@@ -1,4 +1,5 @@
|
||||
#ifdef __UCE_WASM_CORE__
|
||||
#include <cmath>
|
||||
#include "types.h"
|
||||
#include "functionlib.h"
|
||||
#include "sys.h"
|
||||
@@ -16,6 +17,10 @@ int uce_host_file_exists(const char* path, size_t path_len, const char* current,
|
||||
size_t uce_host_file_read(const char* path, size_t path_len, const char* current, size_t current_len, char* buf, size_t cap);
|
||||
int uce_host_file_write(const char* path, size_t path_len, const char* current, size_t current_len, const char* content, size_t content_len, int append);
|
||||
void uce_host_file_unlink(const char* path, size_t path_len, const char* current, size_t current_len);
|
||||
int uce_host_task_spawn(const char* key, size_t key_len, uint64_t callback_id, double interval, uint64_t timeout, int repeat);
|
||||
int uce_host_task_pid(const char* key, size_t key_len);
|
||||
int uce_host_task_kill(int pid, int sig);
|
||||
unsigned int uce_host_sleep_us(uint64_t usec);
|
||||
}
|
||||
|
||||
static String wasm_current_unit_file()
|
||||
@@ -82,9 +87,55 @@ f64 config_f64(String key, f64 fallback) { return(context ? config_map_f64(conte
|
||||
bool config_bool(String key, bool fallback) { return(context ? config_map_bool(context->server->config, key, fallback) : fallback); }
|
||||
f64 time_precise() { return(uce_host_time_precise()); }
|
||||
u64 time() { return(uce_host_time()); }
|
||||
String time_format_local(String format, u64 timestamp) { (void)format; return(std::to_string(timestamp ? timestamp : time())); }
|
||||
String time_format_utc(String format, u64 timestamp) { (void)format; return(std::to_string(timestamp ? timestamp : time())); }
|
||||
String time_format_relative(u64 timestamp, String format_very_recent, u64 medium_recency_seconds, String format_medium_recent, u64 not_recent_seconds, String format_not_recent) { (void)format_very_recent; (void)medium_recency_seconds; (void)format_medium_recent; (void)not_recent_seconds; (void)format_not_recent; return(std::to_string(timestamp)); }
|
||||
// The native build shells out to `date`; the wasm core has no shell, so it
|
||||
// formats with wasi-libc strftime (no TZ data → local == UTC, acceptable).
|
||||
static String wasm_time_strftime(String format, u64 timestamp, bool utc)
|
||||
{
|
||||
if(timestamp == 0)
|
||||
timestamp = time();
|
||||
time_t t = (time_t)timestamp;
|
||||
struct tm tmv;
|
||||
if(utc)
|
||||
gmtime_r(&t, &tmv);
|
||||
else
|
||||
localtime_r(&t, &tmv);
|
||||
char buffer[512];
|
||||
size_t n = strftime(buffer, sizeof(buffer), format.c_str(), &tmv);
|
||||
return(String(buffer, n));
|
||||
}
|
||||
String time_format_local(String format, u64 timestamp) { return(wasm_time_strftime(format, timestamp, false)); }
|
||||
String time_format_utc(String format, u64 timestamp)
|
||||
{
|
||||
if(format == "RFC1123")
|
||||
format = "%a, %d %b %Y %T GMT";
|
||||
return(wasm_time_strftime(format, timestamp, true));
|
||||
}
|
||||
static String wasm_time_expand_delta(String format, u64 timestamp, u64 now_timestamp)
|
||||
{
|
||||
u64 delta_seconds = now_timestamp > timestamp ? now_timestamp - timestamp : 0;
|
||||
format = replace(format, "%deltaY", std::to_string(delta_seconds / (60 * 60 * 24 * 365)));
|
||||
format = replace(format, "%deltam", std::to_string(delta_seconds / (60 * 60 * 24 * 30)));
|
||||
format = replace(format, "%deltad", std::to_string(delta_seconds / (60 * 60 * 24)));
|
||||
format = replace(format, "%deltaH", std::to_string(delta_seconds / (60 * 60)));
|
||||
format = replace(format, "%deltaM", std::to_string(delta_seconds / 60));
|
||||
format = replace(format, "%deltaS", std::to_string(delta_seconds));
|
||||
return(format);
|
||||
}
|
||||
String time_format_relative(u64 timestamp, String format_very_recent, u64 medium_recency_seconds, String format_medium_recent, u64 not_recent_seconds, String format_not_recent)
|
||||
{
|
||||
u64 now_timestamp = time();
|
||||
u64 delta_seconds = now_timestamp > timestamp ? now_timestamp - timestamp : 0;
|
||||
format_very_recent = first(format_very_recent, "just now");
|
||||
medium_recency_seconds = medium_recency_seconds > 0 ? medium_recency_seconds : 90;
|
||||
format_medium_recent = first(format_medium_recent, "%deltaM minutes ago");
|
||||
not_recent_seconds = not_recent_seconds > 0 ? not_recent_seconds : 90 * 60;
|
||||
format_not_recent = first(format_not_recent, "%deltaH hours ago");
|
||||
if(delta_seconds < medium_recency_seconds)
|
||||
return(wasm_time_expand_delta(format_very_recent, timestamp, now_timestamp));
|
||||
if(delta_seconds < not_recent_seconds)
|
||||
return(wasm_time_expand_delta(format_medium_recent, timestamp, now_timestamp));
|
||||
return(wasm_time_expand_delta(format_not_recent, timestamp, now_timestamp));
|
||||
}
|
||||
u64 time_parse(String time_String) { char* end = 0; unsigned long long v = strtoull(time_String.c_str(), &end, 10); return(end && *end == 0 ? (u64)v : 0); }
|
||||
u64 socket_connect(String host, short port) { (void)host; (void)port; return(0); }
|
||||
void socket_close(u64 sockfd) { (void)sockfd; }
|
||||
@@ -112,11 +163,38 @@ bool memcache_delete(u64 connection, String key) { (void)connection; (void)key;
|
||||
String memcache_get(u64 connection, String key, String default_value) { (void)connection; (void)key; return(default_value); }
|
||||
StringMap memcache_get_multiple(u64 connection, StringList keys) { (void)connection; (void)keys; return(StringMap()); }
|
||||
void on_segfault(int sig) { (void)sig; }
|
||||
int task_kill(pid_t pid, int sig) { (void)pid; (void)sig; return(-1); }
|
||||
|
||||
static u64 wasm_next_task_callback_id = 1;
|
||||
static std::map<u64, std::function<void()>> wasm_task_callbacks;
|
||||
|
||||
extern "C" int uce_wasm_task_run(uint64_t callback_id)
|
||||
{
|
||||
auto it = wasm_task_callbacks.find(callback_id);
|
||||
if(it == wasm_task_callbacks.end())
|
||||
return(1);
|
||||
it->second();
|
||||
return(0);
|
||||
}
|
||||
|
||||
int task_kill(pid_t pid, int sig) { return(uce_host_task_kill(pid, sig)); }
|
||||
String runtime_safe_key(String key, String label) { (void)label; return(key); }
|
||||
pid_t task(String key, std::function<void()> exec_after_spawn, u64 timeout) { (void)key; (void)exec_after_spawn; (void)timeout; return(0); }
|
||||
pid_t task_repeat(String key, f64 interval, std::function<void()> exec_after_spawn, u64 timeout) { (void)key; (void)interval; (void)exec_after_spawn; (void)timeout; return(0); }
|
||||
pid_t task_pid(String key) { (void)key; return(0); }
|
||||
pid_t task(String key, std::function<void()> exec_after_spawn, u64 timeout)
|
||||
{
|
||||
u64 id = wasm_next_task_callback_id++;
|
||||
wasm_task_callbacks[id] = exec_after_spawn;
|
||||
return((pid_t)uce_host_task_spawn(key.data(), key.size(), id, 0.0, timeout, 0));
|
||||
}
|
||||
pid_t task_repeat(String key, f64 interval, std::function<void()> exec_after_spawn, u64 timeout)
|
||||
{
|
||||
if(!(interval > 0) || !std::isfinite(interval))
|
||||
return(0);
|
||||
u64 id = wasm_next_task_callback_id++;
|
||||
wasm_task_callbacks[id] = exec_after_spawn;
|
||||
return((pid_t)uce_host_task_spawn(key.data(), key.size(), id, interval, timeout, 1));
|
||||
}
|
||||
pid_t task_pid(String key) { return((pid_t)uce_host_task_pid(key.data(), key.size())); }
|
||||
extern "C" unsigned int sleep(unsigned int seconds) { return(uce_host_sleep_us((uint64_t)seconds * 1000000ull)); }
|
||||
extern "C" int usleep(unsigned int usec) { uce_host_sleep_us(usec); return(0); }
|
||||
pid_t server_start_http(String key, String socket_fn_or_port, String call_uce_filename, String call_function) { (void)key; (void)socket_fn_or_port; (void)call_uce_filename; (void)call_function; return(0); }
|
||||
bool server_stop(String key) { (void)key; return(false); }
|
||||
StringMap default_config()
|
||||
|
||||
Reference in New Issue
Block a user