Merge pull request #344 from gwsystems/hashmap

feat: Initial scratch storage implementation
master
Sean McBride 3 years ago committed by GitHub
commit 555215ab77
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -22,11 +22,16 @@ all: \
gocr.install \ gocr.install \
gps_ekf.install \ gps_ekf.install \
license_plate_detection.install \ license_plate_detection.install \
resize_image.install resize_image.install \
scratch_storage_get.install \
scratch_storage_set.install \
scratch_storage_delete.install \
scratch_storage_upsert.install \
.PHONY: clean .PHONY: clean
clean: clean:
@make -C wasm_apps clean @make -C wasm_apps clean
@make -C scratch_storage clean
@rm -rf dist @rm -rf dist
@rm -rf ../runtime/bin/*.so @rm -rf ../runtime/bin/*.so
@ -39,6 +44,23 @@ wasm_apps/dist/%.wasm:
../libsledge/dist/libsledge.a: ../libsledge/dist/ ../libsledge/dist/libsledge.a: ../libsledge/dist/
make -C .. libsledge make -C .. libsledge
PHONY: scratch_storage
scratch_storage:
make -C scratch_storage all
PHONY: scratch_storage.install
scratch_storage.install: \
scratch_storage_get.install \
scratch_storage_set.install \
scratch_storage_delete.install \
scratch_storage_upsert.install
scratch_storage/scratch_storage_%.wasm:
make -C scratch_storage all
dist/scratch_storage_%.bc: scratch_storage/scratch_storage_%.wasm dist
${AWSMCC} ${AWSMFLAGS} $< -o $@
dist/%.bc: ./wasm_apps/dist/%.wasm dist dist/%.bc: ./wasm_apps/dist/%.wasm dist
${AWSMCC} ${AWSMFLAGS} $< -o $@ ${AWSMCC} ${AWSMFLAGS} $< -o $@
@ -88,3 +110,15 @@ stack_overflow.install: ../runtime/bin/stack_overflow.wasm.so
.PHONY: html.install .PHONY: html.install
html.install: ../runtime/bin/html.wasm.so html.install: ../runtime/bin/html.wasm.so
.PHONY: scratch_storage_get.install
scratch_storage_get.install: ../runtime/bin/scratch_storage_get.wasm.so
.PHONY: scratch_storage_set.install
scratch_storage_set.install: ../runtime/bin/scratch_storage_set.wasm.so
.PHONY: scratch_storage_delete.install
scratch_storage_delete.install: ../runtime/bin/scratch_storage_delete.wasm.so
.PHONY: scratch_storage_upsert.install
scratch_storage_upsert.install: ../runtime/bin/scratch_storage_upsert.wasm.so

@ -0,0 +1,24 @@
include ../wasm_apps/common.mk
.PHONY: all
all: \
scratch_storage_get.wasm \
scratch_storage_set.wasm \
scratch_storage_delete.wasm \
scratch_storage_upsert.wasm \
.PHONY: clean
clean:
@rm -f scratch_storage_set.wa* scratch_storage_get.wa* scratch_storage_delete.wa* scratch_storage_upsert.wa*
scratch_storage_set.wasm: scratch_storage_set.c
@${WASMCC} ${WASMCFLAGS} ${WASMLDFLAGS} $^ -o $@
scratch_storage_get.wasm: scratch_storage_get.c
@${WASMCC} ${WASMCFLAGS} ${WASMLDFLAGS} $^ -o $@
scratch_storage_delete.wasm: scratch_storage_delete.c
@${WASMCC} ${WASMCFLAGS} ${WASMLDFLAGS} $^ -o $@
scratch_storage_upsert.wasm: scratch_storage_upsert.c
@${WASMCC} ${WASMCFLAGS} ${WASMLDFLAGS} $^ -o $@

@ -0,0 +1,32 @@
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern int scratch_storage_delete(void *key, uint32_t key_len)
__attribute__((__import_module__("scratch_storage"), __import_name__("delete")));
int
main(int argc, char **argv)
{
if (argc < 2) {
fprintf(stderr, "%s <key>", argv[0]);
return 0;
}
char *key = argv[1];
if (key == NULL || strlen(key) < 0) {
fprintf(stderr, "%s <key>", argv[0]);
return 0;
}
int rc = scratch_storage_delete(key, strlen(key));
if (rc == 1) {
printf("Key '%s' not found\n", key);
return 0;
} else {
printf("Key %s deleted\n", key);
}
};

@ -0,0 +1,38 @@
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern int scratch_storage_get(void *key, uint32_t key_len, void *buf, uint32_t buf_len)
__attribute__((__import_module__("scratch_storage"), __import_name__("get")));
extern uint32_t scratch_storage_get_size(void *key, uint32_t key_len)
__attribute__((__import_module__("scratch_storage"), __import_name__("get_size")));
int
main(int argc, char **argv)
{
if (argc < 2) {
fprintf(stderr, "%s <key>", argv[0]);
return 0;
}
char *key = argv[1];
if (key == NULL || strlen(key) < 0) {
fprintf(stderr, "%s <key>", argv[0]);
return 0;
}
uint32_t val_size = scratch_storage_get_size(key, strlen(key));
char *buf = calloc(val_size + 1, sizeof(char));
int rc = scratch_storage_get(key, strlen(key), buf, val_size);
assert(rc != 2);
if (rc == 1) {
printf("Key '%s' not found\n", key);
return 0;
} else {
printf("Key %s resolved to value of size %u with contents %s\n", key, val_size, buf);
}
};

@ -0,0 +1,35 @@
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern int scratch_storage_set(void *key, uint32_t key_len, void *value, uint32_t value_len)
__attribute__((__import_module__("scratch_storage"), __import_name__("set")));
int
main(int argc, char **argv)
{
if (argc < 3) {
fprintf(stderr, "%s <key> <value>", argv[0]);
return 0;
}
char *key = argv[1];
char *value = argv[2];
if (key == NULL || strlen(key) < 0 || value == NULL || strlen(value) < 0) {
fprintf(stderr, "%s <key> <value>", argv[0]);
return 0;
}
int rc = scratch_storage_set(key, strlen(key), value, strlen(value));
if (rc == 1) {
printf("Key %s was already present\n", key);
return 0;
}
assert(rc == 0);
printf("Key %s set to value %s\n", key, value);
return rc;
};

@ -0,0 +1,28 @@
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern int scratch_storage_upsert(void *key, uint32_t key_len, void *value, uint32_t value_len)
__attribute__((__import_module__("scratch_storage"), __import_name__("upsert")));
int
main(int argc, char **argv)
{
if (argc < 3) {
fprintf(stderr, "%s <key> <value>", argv[0]);
return 0;
}
char *key = argv[1];
char *value = argv[2];
if (key == NULL || strlen(key) < 0 || value == NULL || strlen(value) < 0) {
fprintf(stderr, "%s <key> <value>", argv[0]);
return 0;
}
scratch_storage_upsert(key, strlen(key), value, strlen(value));
printf("Key %s set to value %s\n", key, value);
};

@ -1 +1 @@
Subproject commit 456edf5cecd7edc36314ba87e2d76ebf8cf1b5db Subproject commit 20a7c88816c8f8882e03d42c76ff8c1e72bfeaec

@ -26,7 +26,7 @@ dist:
dist/%.o: src/%.c dist dist/%.o: src/%.c dist
clang ${CFLAGS} -c ${INCLUDES} -o $@ $< clang ${CFLAGS} -c ${INCLUDES} -o $@ $<
dist/libsledge.a: dist/control_instructions.o dist/memory_instructions.o dist/numeric_instructions.o dist/table_instructions.o dist/variable_instructions.o dist/instantiation.o dist/wasi_snapshot_preview1.o dist/libsledge.a: dist/control_instructions.o dist/memory_instructions.o dist/numeric_instructions.o dist/table_instructions.o dist/variable_instructions.o dist/instantiation.o dist/wasi_snapshot_preview1.o dist/sledge_extensions.o
ar rcs dist/libsledge.a $^ ar rcs dist/libsledge.a $^
clean: clean:

@ -249,3 +249,10 @@ uint32_t sledge_abi__wasi_snapshot_preview1_sock_send(__wasi_fd_t fd, __wasi_siz
__wasi_size_t nbytes_retoffset); __wasi_size_t nbytes_retoffset);
uint32_t sledge_abi__wasi_snapshot_preview1_sock_shutdown(__wasi_fd_t fd, uint32_t how); uint32_t sledge_abi__wasi_snapshot_preview1_sock_shutdown(__wasi_fd_t fd, uint32_t how);
uint32_t sledge_abi__scratch_storage_get_size(uint32_t key_offset, uint32_t key_len);
int sledge_abi__scratch_storage_get(uint32_t key_offset, uint32_t key_size, uint32_t buf_offset, uint32_t buf_len);
int sledge_abi__scratch_storage_set(uint32_t key_offset, uint32_t key_len, uint32_t value_offset, uint32_t value_len);
int sledge_abi__scratch_storage_delete(uint32_t key_offset, uint32_t key_len);
void
sledge_abi__scratch_storage_upsert(uint32_t key_offset, uint32_t key_len, uint32_t value_offset, uint32_t value_len);

@ -0,0 +1,65 @@
#include <stdint.h>
#include "sledge_abi.h"
#define INLINE __attribute__((always_inline))
/**
* @param key
* @param key_len
* @returns value_size at key or 0 if key not present
*/
INLINE uint32_t
scratch_storage_get_size(uint32_t key_offset, uint32_t key_len)
{
return sledge_abi__scratch_storage_get_size(key_offset, key_len);
}
/**
* @param key_offset
* @param key_len
* @param buf_offset linear memory offset to buffer where value should be copied.
* @param buf_len Size of buffer. Assumed to be size returned by sledge_kv_get_value_size.
* @returns 0 on success, 1 if key missing, 2 if buffer too small
*/
INLINE int
scratch_storage_get(uint32_t key_offset, uint32_t key_len, uint32_t buf_offset, uint32_t buf_len)
{
return sledge_abi__scratch_storage_get(key_offset, key_len, buf_offset, buf_len);
};
/**
* @param key_offset
* @param key_len
* @param value_offset
* @param value_len
* @returns 0 on success, 1 if already present,
*/
INLINE int
scratch_storage_set(uint32_t key_offset, uint32_t key_len, uint32_t value_offset, uint32_t value_len)
{
return sledge_abi__scratch_storage_set(key_offset, key_len, value_offset, value_len);
}
/**
* @param key_offset
* @param key_len
* @returns 0 on success, 1 if not present
*/
INLINE int
scratch_storage_delete(uint32_t key_offset, uint32_t key_len)
{
return sledge_abi__scratch_storage_delete(key_offset, key_len);
}
/**
* @param key_offset
* @param key_len
* @param value_offset
* @param value_len
* @returns 0 on success, 1 if already present,
*/
INLINE void
scratch_storage_upsert(uint32_t key_offset, uint32_t key_len, uint32_t value_offset, uint32_t value_len)
{
sledge_abi__scratch_storage_upsert(key_offset, key_len, value_offset, value_len);
}

@ -5,6 +5,7 @@
#include "arch/getcycles.h" #include "arch/getcycles.h"
#include "runtime.h" #include "runtime.h"
#include "generic_thread.h"
typedef ck_spinlock_mcs_t lock_t; typedef ck_spinlock_mcs_t lock_t;

@ -0,0 +1,191 @@
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include "lock.h"
#include "xmalloc.h"
/* Simple K-V store based on The Practice of Programming by Kernighan and Pike */
/* Bucket count is sized to be a prime that is approximately 20% larger than the desired capacity (6k keys) */
#define MAP_BUCKET_COUNT 7907
#define MAP_HASH jenkins_hash
struct map_node {
struct map_node *next;
uint8_t *key;
uint8_t *value;
uint32_t key_len;
uint32_t value_len;
uint32_t hash;
};
struct map_bucket {
lock_t lock;
struct map_node *head;
};
struct map {
struct map_bucket buckets[MAP_BUCKET_COUNT];
};
static inline void
map_init(struct map *restrict map)
{
for (int i = 0; i < MAP_BUCKET_COUNT; i++) {
map->buckets[i].head = NULL;
LOCK_INIT(&map->buckets[i].lock);
}
};
/* See https://en.wikipedia.org/wiki/Jenkins_hash_function */
static inline uint32_t
jenkins_hash(uint8_t *key, uint32_t key_len)
{
uint32_t i = 0;
uint32_t hash = 0;
while (i != key_len) {
hash += key[i++];
hash += hash << 10;
hash ^= hash >> 6;
}
hash += hash << 3;
hash ^= hash >> 11;
hash += hash << 15;
return hash;
}
static inline uint8_t *
map_get(struct map *map, uint8_t *key, uint32_t key_len, uint32_t *ret_value_len)
{
uint8_t *value = NULL;
uint32_t hash = MAP_HASH(key, key_len);
struct map_bucket *bucket = &map->buckets[hash % MAP_BUCKET_COUNT];
LOCK_LOCK(&bucket->lock);
for (struct map_node *node = bucket->head; node != NULL; node = node->next) {
if (node->hash == hash) {
value = node->value;
*ret_value_len = node->value_len;
goto DONE;
}
}
if (value == NULL) *ret_value_len = 0;
DONE:
LOCK_UNLOCK(&bucket->lock);
return value;
}
static inline bool
map_set(struct map *map, uint8_t *key, uint32_t key_len, uint8_t *value, uint32_t value_len)
{
bool did_set = false;
uint32_t hash = MAP_HASH(key, key_len);
struct map_bucket *bucket = &map->buckets[hash % MAP_BUCKET_COUNT];
LOCK_LOCK(&bucket->lock);
for (struct map_node *node = bucket->head; node != NULL; node = node->next) {
if (node->hash == hash) goto DONE;
}
struct map_node *new_node = (struct map_node *)xmalloc(sizeof(struct map_node));
*(new_node) = (struct map_node){ .hash = hash,
.key = xmalloc(key_len),
.key_len = key_len,
.value = xmalloc(value_len),
.value_len = value_len,
.next = bucket->head };
// Copy Key and Value
memcpy(new_node->key, key, key_len);
memcpy(new_node->value, value, value_len);
bucket->head = new_node;
did_set = true;
DONE:
LOCK_UNLOCK(&bucket->lock);
return did_set;
}
/**
* @returns boolean if node was deleted or not
*/
static inline bool
map_delete(struct map *map, uint8_t *key, uint32_t key_len)
{
bool did_delete = false;
uint32_t hash = MAP_HASH(key, key_len);
struct map_bucket *bucket = &map->buckets[hash % MAP_BUCKET_COUNT];
LOCK_LOCK(&bucket->lock);
struct map_node *prev = bucket->head;
if (prev != NULL && prev->hash == hash) {
bucket->head = prev->next;
free(prev->key);
free(prev->value);
free(prev);
did_delete = true;
goto DONE;
}
for (struct map_node *node = prev->next; node != NULL; prev = node, node = node->next) {
prev->next = node->next;
free(node->key);
free(node->value);
free(node);
did_delete = true;
goto DONE;
}
DONE:
LOCK_UNLOCK(&bucket->lock);
return did_delete;
}
static inline void
map_upsert(struct map *map, uint8_t *key, uint32_t key_len, uint8_t *value, uint32_t value_len)
{
uint32_t hash = MAP_HASH(key, key_len);
struct map_bucket *bucket = &map->buckets[hash % MAP_BUCKET_COUNT];
LOCK_LOCK(&bucket->lock);
for (struct map_node *node = bucket->head; node != NULL; node = node->next) {
if (node->hash == hash) {
node->value_len = value_len;
node->value = realloc(node->value, value_len);
assert(node->value);
memcpy(node->value, value, value_len);
goto DONE;
}
}
struct map_node *new_node = (struct map_node *)xmalloc(sizeof(struct map_node));
*(new_node) = (struct map_node){ .hash = hash,
.key = xmalloc(key_len),
.key_len = key_len,
.value = xmalloc(value_len),
.value_len = value_len,
.next = bucket->head };
assert(new_node->key);
assert(new_node->value);
// Copy Key and Value
memcpy(new_node->key, key, key_len);
memcpy(new_node->value, value, value_len);
bucket->head = new_node;
DONE:
LOCK_UNLOCK(&bucket->lock);
}

@ -73,7 +73,6 @@ route_config_validate(struct route_config *config, bool *did_set)
if (did_set[route_config_member_http_resp_content_type] == false) { if (did_set[route_config_member_http_resp_content_type] == false) {
debuglog("http_resp_content_type not set, defaulting to text/plain\n"); debuglog("http_resp_content_type not set, defaulting to text/plain\n");
config->http_resp_content_type = "text/plain"; config->http_resp_content_type = "text/plain";
return -1;
} }
if (scheduler == SCHEDULER_EDF) { if (scheduler == SCHEDULER_EDF) {

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "http_router.h" #include "http_router.h"
#include "map.h"
#include "module_database.h" #include "module_database.h"
#include "tcp_server.h" #include "tcp_server.h"
@ -9,4 +10,5 @@ struct tenant {
struct tcp_server tcp_server; struct tcp_server tcp_server;
http_router_t router; http_router_t router;
struct module_database module_db; struct module_database module_db;
struct map scratch_storage;
}; };

@ -37,6 +37,7 @@ tenant_alloc(struct tenant_config *config)
tcp_server_init(&tenant->tcp_server, config->port); tcp_server_init(&tenant->tcp_server, config->port);
http_router_init(&tenant->router, config->routes_len); http_router_init(&tenant->router, config->routes_len);
module_database_init(&tenant->module_db); module_database_init(&tenant->module_db);
map_init(&tenant->scratch_storage);
for (int i = 0; i < config->routes_len; i++) { for (int i = 0; i < config->routes_len; i++) {
struct module *module = module_database_find_by_path(&tenant->module_db, config->routes[i].path); struct module *module = module_database_find_by_path(&tenant->module_db, config->routes[i].path);

@ -0,0 +1,14 @@
#pragma once
#include <stdlib.h>
#include "likely.h"
#include "panic.h"
static inline void *
xmalloc(size_t size)
{
void *allocation = malloc(size);
if (unlikely(allocation == NULL)) panic("xmalloc failed!\n");
return allocation;
}

@ -1,4 +1,5 @@
#include "current_sandbox.h" #include "current_sandbox.h"
#include "map.h"
#include "sandbox_set_as_running_sys.h" #include "sandbox_set_as_running_sys.h"
#include "sandbox_set_as_running_user.h" #include "sandbox_set_as_running_user.h"
#include "sledge_abi.h" #include "sledge_abi.h"
@ -1039,3 +1040,126 @@ sledge_abi__wasi_snapshot_preview1_sock_shutdown(__wasi_fd_t fd, uint32_t how)
{ {
return wasi_unsupported_syscall(__func__); return wasi_unsupported_syscall(__func__);
} }
/**
* @param key
* @param key_len
* @returns value_len at key or 0 if key not present
*/
EXPORT uint32_t
sledge_abi__scratch_storage_get_size(uint32_t key_offset, uint32_t key_len)
{
struct sandbox *sandbox = current_sandbox_get();
sandbox_syscall(sandbox);
uint8_t *key = (uint8_t *)get_memory_ptr_for_runtime(key_offset, key_len);
uint32_t value_len;
map_get(&sandbox->tenant->scratch_storage, key, key_len, &value_len);
sandbox_return(sandbox);
return value_len;
}
EXPORT int
sledge_abi__scratch_storage_get(uint32_t key_offset, uint32_t key_len, uint32_t buf_offset, uint32_t buf_len)
{
int rc = 0;
struct sandbox *sandbox = current_sandbox_get();
sandbox_syscall(sandbox);
uint8_t *key = (uint8_t *)get_memory_ptr_for_runtime(key_offset, key_len);
uint8_t *buf = (uint8_t *)get_memory_ptr_for_runtime(buf_offset, buf_len);
uint32_t value_len;
uint8_t *value = map_get(&sandbox->tenant->scratch_storage, key, key_len, &value_len);
if (value == NULL) {
rc = 1;
goto DONE;
} else if (value_len > buf_len) {
rc = 2;
goto DONE;
} else {
memcpy(buf, value, value_len);
rc = 0;
}
DONE:
sandbox_return(sandbox);
return rc;
}
/**
* @param key_offset
* @param key_len
* @param value_offset
* @param value_len
* @returns 0 on success, 1 if already present,
*/
EXPORT int
sledge_abi__scratch_storage_set(uint32_t key_offset, uint32_t key_len, uint32_t value_offset, uint32_t value_len)
{
int rc = 0;
struct sandbox *sandbox = current_sandbox_get();
sandbox_syscall(sandbox);
uint8_t *key = (uint8_t *)get_memory_ptr_for_runtime(key_offset, key_len);
uint8_t *value = (uint8_t *)get_memory_ptr_for_runtime(value_offset, value_len);
bool did_set = map_set(&sandbox->tenant->scratch_storage, key, key_len, value, value_len);
DONE:
sandbox_return(sandbox);
return did_set ? 0 : 1;
}
/**
* @param key_offset
* @param key_len
* @returns 0 on success, 1 if not present
*/
EXPORT int
sledge_abi__scratch_storage_delete(uint32_t key_offset, uint32_t key_len)
{
int rc = 0;
struct sandbox *sandbox = current_sandbox_get();
sandbox_syscall(sandbox);
uint8_t *key = (uint8_t *)get_memory_ptr_for_runtime(key_offset, key_len);
bool did_delete = map_delete(&sandbox->tenant->scratch_storage, key, key_len);
DONE:
sandbox_return(sandbox);
return did_delete ? 0 : 1;
}
/**
* @param key_offset
* @param key_len
* @param value_offset
* @param value_len
*/
EXPORT void
sledge_abi__scratch_storage_upsert(uint32_t key_offset, uint32_t key_len, uint32_t value_offset, uint32_t value_len)
{
struct sandbox *sandbox = current_sandbox_get();
sandbox_syscall(sandbox);
uint8_t *key = (uint8_t *)get_memory_ptr_for_runtime(key_offset, key_len);
uint8_t *value = (uint8_t *)get_memory_ptr_for_runtime(value_offset, value_len);
map_upsert(&sandbox->tenant->scratch_storage, key, key_len, value, value_len);
sandbox_return(sandbox);
}

@ -0,0 +1,3 @@
res
perf.data
perf.data.old

@ -0,0 +1,46 @@
RUNTIME_DIR=../../runtime/
SLEDGE_BINARY_DIR=${RUNTIME_DIR}/bin
SLEDGE_TESTS_DIR=${RUNTIME_DIR}/tests
HOSTNAME=localhost
all: run
clean:
make -C ${RUNTIME_DIR} clean
make -C ${SLEDGE_TESTS_DIR} clean
rm -f ${SLEDGE_BINARY_DIR}/html.wasm.so
${SLEDGE_BINARY_DIR}/sledgert:
make -C ${RUNTIME_DIR} runtime
.PHONY: sledgert
sledgert: ${SLEDGE_BINARY_DIR}/sledgert
${SLEDGE_BINARY_DIR}/scratch_storage.wasm.so:
make -C ../../applications scratch_storage.install
.PHONY: scratch_storage_get
scratch_storage_get: ${SLEDGE_BINARY_DIR}/scratch_storage_get.wasm.so
.PHONY: scratch_storage_set
scratch_storage_set: ${SLEDGE_BINARY_DIR}/scratch_storage_set.wasm.so
run: sledgert scratch_storage_get scratch_storage_set
LD_LIBRARY_PATH=${SLEDGE_BINARY_DIR} ${SLEDGE_BINARY_DIR}/sledgert spec.json
debug: sledgert scratch_storage_get scratch_storage_set
SLEDGE_DISABLE_PREEMPTION=true SLEDGE_NWORKERS=1 \
LD_LIBRARY_PATH=${SLEDGE_BINARY_DIR} gdb ${SLEDGE_BINARY_DIR}/sledgert \
--eval-command="handle SIGUSR1 noprint nostop" \
--eval-command="handle SIGPIPE noprint nostop" \
--eval-command="set pagination off" \
--eval-command="run spec.json"
client-upsert-multi:
hey -z 6s -cpus 4 -c 100 -t 0 -o csv -m GET "http://${HOSTNAME}:1337/upsert?test&wakka2"
client-get-multi:
hey -z 6s -cpus 4 -c 100 -t 0 -o csv -m GET "http://${HOSTNAME}:1337/get?test"
client:
http :1337/scratch_storage

@ -0,0 +1,2 @@
SLEDGE_SCHEDULER=EDF
SLEDGE_DISABLE_PREEMPTION=true

@ -0,0 +1,3 @@
SLEDGE_SCHEDULER=EDF
SLEDGE_DISABLE_PREEMPTION=false
SLEDGE_SIGALRM_HANDLER=TRIAGED

@ -0,0 +1,2 @@
SLEDGE_SCHEDULER=FIFO
SLEDGE_DISABLE_PREEMPTION=true

@ -0,0 +1,2 @@
SLEDGE_SCHEDULER=FIFO
SLEDGE_DISABLE_PREEMPTION=false

@ -0,0 +1,13 @@
#!/bin/bash
if ! command -v hey > /dev/null; then
HEY_URL=https://hey-release.s3.us-east-2.amazonaws.com/hey_linux_amd64
wget $HEY_URL -O hey
chmod +x hey
if [[ $(whoami) == "root" ]]; then
mv hey /usr/bin/hey
else
sudo mv hey /usr/bin/hey
fi
fi

@ -0,0 +1,44 @@
[
{
"name": "gwu",
"port": 1337,
"routes": [
{
"route": "/set",
"path": "scratch_storage_set.wasm.so",
"expected-execution-us": 10000000,
"admissions-percentile": 70,
"relative-deadline-us": 20000000,
"http-resp-content-type": "text/plain",
"http-resp-size": 1024
},
{
"route": "/get",
"path": "scratch_storage_get.wasm.so",
"expected-execution-us": 10000000,
"admissions-percentile": 70,
"relative-deadline-us": 20000000,
"http-resp-content-type": "text/plain",
"http-resp-size": 1024
},
{
"route": "/delete",
"path": "scratch_storage_delete.wasm.so",
"expected-execution-us": 10000000,
"admissions-percentile": 70,
"relative-deadline-us": 20000000,
"http-resp-content-type": "text/plain",
"http-resp-size": 1024
},
{
"route": "/upsert",
"path": "scratch_storage_upsert.wasm.so",
"expected-execution-us": 10000000,
"admissions-percentile": 70,
"relative-deadline-us": 20000000,
"http-resp-content-type": "text/plain",
"http-resp-size": 1024
}
]
}
]
Loading…
Cancel
Save