diff --git a/applications/Makefile b/applications/Makefile index 202a9fc..332a346 100644 --- a/applications/Makefile +++ b/applications/Makefile @@ -122,3 +122,6 @@ 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 + +.PHONY: depth_to_xyz.install +depth_to_xyz.install: ../runtime/bin/depth_to_xyz.wasm.so diff --git a/applications/wasm_apps b/applications/wasm_apps index 0b9f67d..726b080 160000 --- a/applications/wasm_apps +++ b/applications/wasm_apps @@ -1 +1 @@ -Subproject commit 0b9f67d75fd9dab652e1995e7adf91806080523b +Subproject commit 726b0804777ef346308f9dfcdf928032c28226a8 diff --git a/runtime/Makefile b/runtime/Makefile index 2bbcfd1..2fe298e 100644 --- a/runtime/Makefile +++ b/runtime/Makefile @@ -59,7 +59,6 @@ BINARY_NAME=sledgert # CFLAGS += -DLOG_ADMISSIONS_CONTROL # CFLAGS += -DLOG_CONTEXT_SWITCHES # CFLAGS += -DLOG_HTTP_PARSER -# CFLAGS += -DLOG_LOCK_OVERHEAD # CFLAGS += -DLOG_TENANT_LOADING # CFLAGS += -DLOG_PREEMPTION # CFLAGS += -DLOG_SANDBOX_ALLOCATION diff --git a/runtime/include/generic_thread.h b/runtime/include/generic_thread.h deleted file mode 100644 index 5069d9f..0000000 --- a/runtime/include/generic_thread.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include -#include - -extern thread_local uint64_t generic_thread_lock_duration; -extern thread_local uint64_t generic_thread_lock_longest; -extern thread_local uint64_t generic_thread_start_timestamp; - -void generic_thread_dump_lock_overhead(void); -void generic_thread_initialize(void); diff --git a/runtime/include/http_session.h b/runtime/include/http_session.h index 21840df..fc7973e 100644 --- a/runtime/include/http_session.h +++ b/runtime/include/http_session.h @@ -38,9 +38,10 @@ enum http_session_state HTTP_SESSION_EXECUTION_COMPLETE, HTTP_SESSION_SENDING_RESPONSE_HEADER, HTTP_SESSION_SEND_RESPONSE_HEADER_BLOCKED, - HTTP_SESSION_SENDING_RESPONSE, - HTTP_SESSION_SEND_RESPONSE_BLOCKED, - HTTP_SESSION_SENT_RESPONSE + HTTP_SESSION_SENT_RESPONSE_HEADER, + HTTP_SESSION_SENDING_RESPONSE_BODY, + HTTP_SESSION_SEND_RESPONSE_BODY_BLOCKED, + HTTP_SESSION_SENT_RESPONSE_BODY }; struct http_session { @@ -218,6 +219,9 @@ static inline int http_session_send_response_header(struct http_session *session, void_star_cb on_eagain) { assert(session != NULL); + assert(session->state == HTTP_SESSION_EXECUTION_COMPLETE + || session->state == HTTP_SESSION_SEND_RESPONSE_HEADER_BLOCKED); + session->state = HTTP_SESSION_SENDING_RESPONSE_HEADER; while (session->response_header_length > session->response_header_written) { ssize_t sent = @@ -232,6 +236,8 @@ http_session_send_response_header(struct http_session *session, void_star_cb on_ } } + session->state = HTTP_SESSION_SENT_RESPONSE_HEADER; + return 0; } @@ -246,6 +252,10 @@ http_session_send_response_body(struct http_session *session, void_star_cb on_ea { assert(session != NULL); + assert(session->state == HTTP_SESSION_SENT_RESPONSE_HEADER + || session->state == HTTP_SESSION_SEND_RESPONSE_BODY_BLOCKED); + session->state = HTTP_SESSION_SENDING_RESPONSE_BODY; + while (session->response_buffer_written < session->response_buffer.length) { ssize_t sent = tcp_session_send(session->socket, @@ -259,6 +269,7 @@ http_session_send_response_body(struct http_session *session, void_star_cb on_ea } } + session->state = HTTP_SESSION_SENT_RESPONSE_BODY; return 0; } @@ -467,6 +478,8 @@ DONE: static inline void http_session_send_response(struct http_session *session, void_star_cb on_eagain) { + assert(session->state == HTTP_SESSION_EXECUTION_COMPLETE); + int rc = http_session_send_response_header(session, on_eagain); /* session blocked and registered to epoll so continue to next handle */ if (unlikely(rc == -EAGAIN)) { @@ -475,6 +488,8 @@ http_session_send_response(struct http_session *session, void_star_cb on_eagain) goto CLOSE; } + assert(session->state == HTTP_SESSION_SENT_RESPONSE_HEADER); + rc = http_session_send_response_body(session, on_eagain); /* session blocked and registered to epoll so continue to next handle */ if (unlikely(rc == -EAGAIN)) { @@ -483,6 +498,8 @@ http_session_send_response(struct http_session *session, void_star_cb on_eagain) goto CLOSE; } + assert(session->state == HTTP_SESSION_SENT_RESPONSE_BODY); + /* Terminal State Logging for Http Session */ session->response_sent_timestamp = __getcycles(); http_session_perf_log_print_entry(session); diff --git a/runtime/include/listener_thread.h b/runtime/include/listener_thread.h index 8a91274..31bd2c1 100644 --- a/runtime/include/listener_thread.h +++ b/runtime/include/listener_thread.h @@ -3,7 +3,6 @@ #include #include -#include "generic_thread.h" #include "http_session.h" #include "module.h" diff --git a/runtime/include/lock.h b/runtime/include/lock.h index 81a7681..1ff0242 100644 --- a/runtime/include/lock.h +++ b/runtime/include/lock.h @@ -1,68 +1,81 @@ #pragma once +#include #include #include #include "arch/getcycles.h" #include "runtime.h" -#include "generic_thread.h" -typedef ck_spinlock_mcs_t lock_t; + +/* A linked list of nodes */ +struct lock_wrapper { + uint64_t longest_held; + uint64_t total_held; + ck_spinlock_mcs_t lock; +}; + +/* A node on the linked list */ +struct lock_node { + struct ck_spinlock_mcs node; + uint64_t time_locked; +}; + +typedef struct lock_wrapper lock_t; +typedef struct lock_node lock_node_t; /** - * Initializes a lock of type lock_t + * Initializes a lock * @param lock - the address of the lock */ -#define LOCK_INIT(lock) ck_spinlock_mcs_init((lock)) +static inline void +lock_init(lock_t *self) +{ + self->total_held = 0; + self->longest_held = 0; + ck_spinlock_mcs_init(&self->lock); +} /** * Checks if a lock is locked * @param lock - the address of the lock * @returns bool if lock is locked */ - -#define LOCK_IS_LOCKED(lock) ck_spinlock_mcs_locked((lock)) +static inline bool +lock_is_locked(lock_t *self) +{ + return ck_spinlock_mcs_locked(&self->lock); +} /** * Locks a lock, keeping track of overhead * @param lock - the address of the lock - * @param unique_variable_name - a unique prefix to hygienically namespace an associated lock/unlock pair + * @param node - node to add to lock */ +static inline void +lock_lock(lock_t *self, lock_node_t *node) +{ + assert(node->time_locked == 0); -#define LOCK_LOCK_WITH_BOOKKEEPING(lock, unique_variable_name) \ - struct ck_spinlock_mcs _hygiene_##unique_variable_name##_node; \ - uint64_t _hygiene_##unique_variable_name##_pre = __getcycles(); \ - ck_spinlock_mcs_lock((lock), &(_hygiene_##unique_variable_name##_node)); \ - uint64_t _hygiene_##unique_variable_name##_duration = (__getcycles() - _hygiene_##unique_variable_name##_pre); \ - if (_hygiene_##unique_variable_name##_duration > generic_thread_lock_longest) { \ - generic_thread_lock_longest = _hygiene_##unique_variable_name##_duration; \ - } \ - generic_thread_lock_duration += _hygiene_##unique_variable_name##_duration; + node->time_locked = __getcycles(); + ck_spinlock_mcs_lock(&self->lock, &node->node); +} /** * Unlocks a lock * @param lock - the address of the lock - * @param unique_variable_name - a unique prefix to hygienically namespace an associated lock/unlock pair + * @param node - node used when calling lock_lock */ -#define LOCK_UNLOCK_WITH_BOOKKEEPING(lock, unique_variable_name) \ - ck_spinlock_mcs_unlock(lock, &(_hygiene_##unique_variable_name##_node)); +static inline void +lock_unlock(lock_t *self, lock_node_t *node) +{ + assert(node->time_locked > 0); -/** - * Locks a lock, keeping track of overhead - * Assumes the availability of DEFAULT as a hygienic prefix for DEFAULT_node and DEFAULT_pre - * - * As such, this API can only be used once in a lexical scope. - * - * Use LOCK_LOCK_WITH_BOOKKEEPING and LOCK_UNLOCK_WITH_BOOKKEEPING if multiple locks are required - * @param lock - the address of the lock - */ -#define LOCK_LOCK(lock) LOCK_LOCK_WITH_BOOKKEEPING(lock, DEFAULT) - -/** - * Unlocks a lock - * Uses lock node NODE_DEFAULT and timestamp PRE_DEFAULT, so this assumes use of LOCK_LOCK - * This API can only be used once in a lexical scope. If this isn't true, use LOCK_LOCK_WITH_BOOKKEEPING and - * LOCK_UNLOCK_WITH_BOOKKEEPING - * @param lock - the address of the lock - */ -#define LOCK_UNLOCK(lock) LOCK_UNLOCK_WITH_BOOKKEEPING(lock, DEFAULT) + ck_spinlock_mcs_unlock(&self->lock, &node->node); + uint64_t now = __getcycles(); + assert(node->time_locked < now); + uint64_t duration = now - node->time_locked; + node->time_locked = 0; + if (unlikely(duration > self->longest_held)) { self->longest_held = duration; } + self->total_held += duration; +} diff --git a/runtime/include/map.h b/runtime/include/map.h index b923af8..a40f9db 100644 --- a/runtime/include/map.h +++ b/runtime/include/map.h @@ -37,7 +37,7 @@ 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); + lock_init(&map->buckets[i].lock); } }; @@ -67,7 +67,8 @@ map_get(struct map *map, uint8_t *key, uint32_t key_len, uint32_t *ret_value_len struct map_bucket *bucket = &map->buckets[hash % MAP_BUCKET_COUNT]; - LOCK_LOCK(&bucket->lock); + lock_node_t node = {}; + lock_lock(&bucket->lock, &node); for (struct map_node *node = bucket->head; node != NULL; node = node->next) { if (node->hash == hash) { value = node->value; @@ -79,7 +80,7 @@ map_get(struct map *map, uint8_t *key, uint32_t key_len, uint32_t *ret_value_len if (value == NULL) *ret_value_len = 0; DONE: - LOCK_UNLOCK(&bucket->lock); + lock_unlock(&bucket->lock, &node); return value; } @@ -90,7 +91,8 @@ map_set(struct map *map, uint8_t *key, uint32_t key_len, uint8_t *value, uint32_ uint32_t hash = MAP_HASH(key, key_len); struct map_bucket *bucket = &map->buckets[hash % MAP_BUCKET_COUNT]; - LOCK_LOCK(&bucket->lock); + lock_node_t node; + lock_lock(&bucket->lock, &node); for (struct map_node *node = bucket->head; node != NULL; node = node->next) { if (node->hash == hash) goto DONE; } @@ -111,7 +113,7 @@ map_set(struct map *map, uint8_t *key, uint32_t key_len, uint8_t *value, uint32_ did_set = true; DONE: - LOCK_UNLOCK(&bucket->lock); + lock_unlock(&bucket->lock, &node); return did_set; } @@ -125,7 +127,8 @@ map_delete(struct map *map, uint8_t *key, uint32_t key_len) uint32_t hash = MAP_HASH(key, key_len); struct map_bucket *bucket = &map->buckets[hash % MAP_BUCKET_COUNT]; - LOCK_LOCK(&bucket->lock); + lock_node_t node; + lock_lock(&bucket->lock, &node); struct map_node *prev = bucket->head; if (prev != NULL && prev->hash == hash) { @@ -147,7 +150,7 @@ map_delete(struct map *map, uint8_t *key, uint32_t key_len) } DONE: - LOCK_UNLOCK(&bucket->lock); + lock_unlock(&bucket->lock, &node); return did_delete; } @@ -156,7 +159,8 @@ map_upsert(struct map *map, uint8_t *key, uint32_t key_len, uint8_t *value, uint { uint32_t hash = MAP_HASH(key, key_len); struct map_bucket *bucket = &map->buckets[hash % MAP_BUCKET_COUNT]; - LOCK_LOCK(&bucket->lock); + lock_node_t node; + lock_lock(&bucket->lock, &node); for (struct map_node *node = bucket->head; node != NULL; node = node->next) { if (node->hash == hash) { @@ -187,5 +191,5 @@ map_upsert(struct map *map, uint8_t *key, uint32_t key_len, uint8_t *value, uint bucket->head = new_node; DONE: - LOCK_UNLOCK(&bucket->lock); + lock_unlock(&bucket->lock, &node); } diff --git a/runtime/include/perf_window.h b/runtime/include/perf_window.h index 50cc054..bfa32e4 100644 --- a/runtime/include/perf_window.h +++ b/runtime/include/perf_window.h @@ -19,10 +19,10 @@ perf_window_initialize(struct perf_window *perf_window) { assert(perf_window != NULL); - LOCK_INIT(&perf_window->lock); + lock_init(&perf_window->lock); perf_window->count = 0; - memset(perf_window->by_duration, 0, sizeof(struct execution_node) * PERF_WINDOW_BUFFER_SIZE); - memset(perf_window->by_termination, 0, sizeof(uint16_t) * PERF_WINDOW_BUFFER_SIZE); + memset(perf_window->by_duration, 0, sizeof(struct execution_node) * perf_window_capacity); + memset(perf_window->by_termination, 0, sizeof(uint16_t) * perf_window_capacity); } @@ -36,10 +36,10 @@ perf_window_initialize(struct perf_window *perf_window) static inline void perf_window_swap(struct perf_window *perf_window, uint16_t first_by_duration_idx, uint16_t second_by_duration_idx) { - assert(LOCK_IS_LOCKED(&perf_window->lock)); + assert(lock_is_locked(&perf_window->lock)); assert(perf_window != NULL); - assert(first_by_duration_idx >= 0 && first_by_duration_idx < PERF_WINDOW_BUFFER_SIZE); - assert(second_by_duration_idx >= 0 && second_by_duration_idx < PERF_WINDOW_BUFFER_SIZE); + assert(first_by_duration_idx < perf_window_capacity); + assert(second_by_duration_idx < perf_window_capacity); uint16_t first_by_termination_idx = perf_window->by_duration[first_by_duration_idx].by_termination_idx; uint16_t second_by_termination_idx = perf_window->by_duration[second_by_duration_idx].by_termination_idx; @@ -51,11 +51,11 @@ perf_window_swap(struct perf_window *perf_window, uint16_t first_by_duration_idx uint64_t first_execution_time = perf_window->by_duration[first_by_duration_idx].execution_time; uint64_t second_execution_time = perf_window->by_duration[second_by_duration_idx].execution_time; - /* Swap Indices in Buffer*/ + /* Swap indices */ perf_window->by_termination[first_by_termination_idx] = second_by_duration_idx; perf_window->by_termination[second_by_termination_idx] = first_by_duration_idx; - /* Swap by_termination_idx */ + /* Swap nodes */ struct execution_node tmp_node = perf_window->by_duration[first_by_duration_idx]; perf_window->by_duration[first_by_duration_idx] = perf_window->by_duration[second_by_duration_idx]; perf_window->by_duration[second_by_duration_idx] = tmp_node; @@ -67,66 +67,73 @@ perf_window_swap(struct perf_window *perf_window, uint16_t first_by_duration_idx == second_execution_time); } +static inline void +perf_window_fill(struct perf_window *perf_window, uint64_t newest_execution_time) +{ + for (uint16_t i = 0; i < perf_window_capacity; i++) { + perf_window->by_termination[i] = i; + perf_window->by_duration[i] = (struct execution_node){ .execution_time = newest_execution_time, + .by_termination_idx = i }; + } + perf_window->count = perf_window_capacity; +} + /** - * Adds a new value to the perf window + * Adds newest_execution_time to the perf window * Not intended to be called directly! * @param perf_window - * @param value + * @param newest_execution_time */ static inline void -perf_window_add(struct perf_window *perf_window, uint64_t value) +perf_window_add(struct perf_window *perf_window, uint64_t newest_execution_time) { assert(perf_window != NULL); + /* Assumption: A successful invocation should run for a non-zero amount of time */ + assert(newest_execution_time > 0); - uint16_t idx_of_oldest; + uint16_t idx_to_replace; + uint64_t previous_execution_time; bool check_up; - if (unlikely(!LOCK_IS_LOCKED(&perf_window->lock))) panic("lock not held when calling perf_window_add\n"); - - /* A successful invocation should run for a non-zero amount of time */ - assert(value > 0); + if (unlikely(!lock_is_locked(&perf_window->lock))) panic("lock not held when calling perf_window_add\n"); - /* If count is 0, then fill entire array with initial execution times */ + /* If perf window is empty, fill all elements with newest_execution_time */ if (perf_window->count == 0) { - for (int i = 0; i < PERF_WINDOW_BUFFER_SIZE; i++) { - perf_window->by_termination[i] = i; - perf_window->by_duration[i] = (struct execution_node){ .execution_time = value, - .by_termination_idx = i }; - } - perf_window->count = PERF_WINDOW_BUFFER_SIZE; + perf_window_fill(perf_window, newest_execution_time); goto done; } - /* Otherwise, replace the oldest value, and then sort */ - idx_of_oldest = perf_window->by_termination[perf_window->count % PERF_WINDOW_BUFFER_SIZE]; - check_up = value > perf_window->by_duration[idx_of_oldest].execution_time; - - perf_window->by_duration[idx_of_oldest].execution_time = value; + /* If full, replace the oldest execution_time. Save the old execution time to know which direction to swap */ + idx_to_replace = perf_window->by_termination[perf_window->count % perf_window_capacity]; + previous_execution_time = perf_window->by_duration[idx_to_replace].execution_time; + perf_window->by_duration[idx_to_replace].execution_time = newest_execution_time; - if (check_up) { - for (uint16_t i = idx_of_oldest; - i + 1 < PERF_WINDOW_BUFFER_SIZE + /* At this point, the by_duration array is partially sorted. The node we overwrote needs to be shifted left or + * right. We can determine which direction to shift by comparing with the previous execution time. */ + if (newest_execution_time > previous_execution_time) { + for (uint16_t i = idx_to_replace; + i + 1 < perf_window_capacity && perf_window->by_duration[i + 1].execution_time < perf_window->by_duration[i].execution_time; i++) { perf_window_swap(perf_window, i, i + 1); } } else { - for (int i = idx_of_oldest; - i - 1 >= 0 + for (uint16_t i = idx_to_replace; + i >= 1 && perf_window->by_duration[i - 1].execution_time > perf_window->by_duration[i].execution_time; i--) { perf_window_swap(perf_window, i, i - 1); } } - /* The idx that we replaces should still point to the same value */ - assert(perf_window->by_duration[perf_window->by_termination[perf_window->count % PERF_WINDOW_BUFFER_SIZE]] + /* The idx that we replaces should still point to the same newest_execution_time */ + assert(perf_window->by_duration[perf_window->by_termination[perf_window->count % perf_window_capacity]] .execution_time - == value); + == newest_execution_time); /* The by_duration array should be ordered by execution time */ #ifndef NDEBUG - for (int i = 1; i < PERF_WINDOW_BUFFER_SIZE; i++) { + for (int i = 1; i < perf_window_capacity; i++) { assert(perf_window->by_duration[i - 1].execution_time <= perf_window->by_duration[i].execution_time); } #endif @@ -152,10 +159,10 @@ perf_window_get_percentile(struct perf_window *perf_window, uint8_t percentile, if (unlikely(perf_window->count == 0)) return 0; - if (likely(perf_window->count >= PERF_WINDOW_BUFFER_SIZE)) - return perf_window->by_duration[precomputed_index].execution_time; + int idx = precomputed_index; + if (unlikely(perf_window->count < perf_window_capacity)) idx = perf_window->count * percentile / 100; - return perf_window->by_duration[perf_window->count * percentile / 100].execution_time; + return perf_window->by_duration[idx].execution_time; } /** diff --git a/runtime/include/perf_window_t.h b/runtime/include/perf_window_t.h index 4d39af4..0cc0f3e 100644 --- a/runtime/include/perf_window_t.h +++ b/runtime/include/perf_window_t.h @@ -1,15 +1,19 @@ #pragma once +#include #include #include "lock.h" -/* Should be Power of 2! */ -#define PERF_WINDOW_BUFFER_SIZE 16 +enum +{ + perf_window_capacity = 32 +}; + +static_assert(perf_window_capacity && !(perf_window_capacity & (perf_window_capacity - 1)), + "perf_window_capacity must be power of 2!"); -#if ((PERF_WINDOW_BUFFER_SIZE == 0) || (PERF_WINDOW_BUFFER_SIZE & (PERF_WINDOW_BUFFER_SIZE - 1)) != 0) -#error "PERF_WINDOW_BUFFER_SIZE must be power of 2!" -#endif +static_assert(perf_window_capacity <= UINT16_MAX, "perf_window_capacity must be indexable by a 16-bit unsigned int"); /* * The by_duration array sorts the last N executions by execution time @@ -24,8 +28,8 @@ struct execution_node { }; struct perf_window { - struct execution_node by_duration[PERF_WINDOW_BUFFER_SIZE]; - uint16_t by_termination[PERF_WINDOW_BUFFER_SIZE]; + struct execution_node by_duration[perf_window_capacity]; + uint16_t by_termination[perf_window_capacity]; uint64_t count; lock_t lock; }; diff --git a/runtime/include/pool.h b/runtime/include/pool.h index fb83743..733664c 100644 --- a/runtime/include/pool.h +++ b/runtime/include/pool.h @@ -4,7 +4,6 @@ #include #include -#include "generic_thread.h" #include "lock.h" #include "ps_list.h" @@ -26,7 +25,7 @@ { \ ps_list_head_init(&self->list); \ self->use_lock = use_lock; \ - if (use_lock) LOCK_INIT(&self->lock); \ + if (use_lock) lock_init(&self->lock); \ } \ \ static inline void STRUCT_NAME##_pool_deinit(struct STRUCT_NAME##_pool *self) \ @@ -44,7 +43,7 @@ static inline struct STRUCT_NAME *STRUCT_NAME##_pool_remove_nolock(struct STRUCT_NAME##_pool *self) \ { \ assert(self != NULL); \ - assert(!self->use_lock || LOCK_IS_LOCKED(&self->lock)); \ + assert(!self->use_lock || lock_is_locked(&self->lock)); \ \ struct STRUCT_NAME *obj = NULL; \ \ @@ -66,9 +65,10 @@ bool is_empty = STRUCT_NAME##_pool_is_empty(self); \ if (is_empty) return obj; \ \ - LOCK_LOCK(&self->lock); \ + lock_node_t node = {}; \ + lock_lock(&self->lock, &node); \ obj = STRUCT_NAME##_pool_remove_nolock(self); \ - LOCK_UNLOCK(&self->lock); \ + lock_unlock(&self->lock, &node); \ return obj; \ } \ \ @@ -76,7 +76,7 @@ { \ assert(self != NULL); \ assert(obj != NULL); \ - assert(!self->use_lock || LOCK_IS_LOCKED(&self->lock)); \ + assert(!self->use_lock || lock_is_locked(&self->lock)); \ \ ps_list_head_add_d(&self->list, obj); \ } \ @@ -87,7 +87,8 @@ assert(obj != NULL); \ assert(self->use_lock); \ \ - LOCK_LOCK(&self->lock); \ + lock_node_t node = {}; \ + lock_lock(&self->lock, &node); \ STRUCT_NAME##_pool_add_nolock(self, obj); \ - LOCK_UNLOCK(&self->lock); \ + lock_unlock(&self->lock, &node); \ } diff --git a/runtime/include/priority_queue.h b/runtime/include/priority_queue.h index dff49d9..0fddfc0 100644 --- a/runtime/include/priority_queue.h +++ b/runtime/include/priority_queue.h @@ -60,7 +60,7 @@ priority_queue_append(struct priority_queue *priority_queue, void *new_item) { assert(priority_queue != NULL); assert(new_item != NULL); - assert(!priority_queue->use_lock || LOCK_IS_LOCKED(&priority_queue->lock)); + assert(!priority_queue->use_lock || lock_is_locked(&priority_queue->lock)); int rc; @@ -85,7 +85,7 @@ static inline bool priority_queue_is_empty(struct priority_queue *priority_queue) { assert(priority_queue != NULL); - assert(!priority_queue->use_lock || LOCK_IS_LOCKED(&priority_queue->lock)); + assert(!priority_queue->use_lock || lock_is_locked(&priority_queue->lock)); return priority_queue->size == 0; } @@ -99,7 +99,7 @@ priority_queue_percolate_up(struct priority_queue *priority_queue) { assert(priority_queue != NULL); assert(priority_queue->get_priority_fn != NULL); - assert(!priority_queue->use_lock || LOCK_IS_LOCKED(&priority_queue->lock)); + assert(!priority_queue->use_lock || lock_is_locked(&priority_queue->lock)); /* If there's only one element, set memoized lookup and early out */ if (priority_queue->size == 1) { @@ -135,7 +135,7 @@ priority_queue_find_smallest_child(struct priority_queue *priority_queue, const assert(priority_queue != NULL); assert(parent_index >= 1 && parent_index <= priority_queue->size); assert(priority_queue->get_priority_fn != NULL); - assert(!priority_queue->use_lock || LOCK_IS_LOCKED(&priority_queue->lock)); + assert(!priority_queue->use_lock || lock_is_locked(&priority_queue->lock)); int left_child_index = 2 * parent_index; int right_child_index = 2 * parent_index + 1; @@ -167,7 +167,7 @@ priority_queue_percolate_down(struct priority_queue *priority_queue, int parent_ { assert(priority_queue != NULL); assert(priority_queue->get_priority_fn != NULL); - assert(!priority_queue->use_lock || LOCK_IS_LOCKED(&priority_queue->lock)); + assert(!priority_queue->use_lock || lock_is_locked(&priority_queue->lock)); assert(!listener_thread_is_running()); bool update_highest_value = parent_index == 1; @@ -217,7 +217,7 @@ priority_queue_dequeue_if_earlier_nolock(struct priority_queue *priority_queue, assert(dequeued_element != NULL); assert(priority_queue->get_priority_fn != NULL); assert(!listener_thread_is_running()); - assert(!priority_queue->use_lock || LOCK_IS_LOCKED(&priority_queue->lock)); + assert(!priority_queue->use_lock || lock_is_locked(&priority_queue->lock)); int return_code; @@ -251,9 +251,10 @@ priority_queue_dequeue_if_earlier(struct priority_queue *priority_queue, void ** { int return_code; - LOCK_LOCK(&priority_queue->lock); + lock_node_t node = {}; + lock_lock(&priority_queue->lock, &node); return_code = priority_queue_dequeue_if_earlier_nolock(priority_queue, dequeued_element, target_deadline); - LOCK_UNLOCK(&priority_queue->lock); + lock_unlock(&priority_queue->lock, &node); return return_code; } @@ -281,7 +282,7 @@ priority_queue_initialize(size_t capacity, bool use_lock, priority_queue_get_pri priority_queue->get_priority_fn = get_priority_fn; priority_queue->use_lock = use_lock; - if (use_lock) LOCK_INIT(&priority_queue->lock); + if (use_lock) lock_init(&priority_queue->lock); return priority_queue; } @@ -332,7 +333,7 @@ static inline int priority_queue_length_nolock(struct priority_queue *priority_queue) { assert(priority_queue != NULL); - assert(!priority_queue->use_lock || LOCK_IS_LOCKED(&priority_queue->lock)); + assert(!priority_queue->use_lock || lock_is_locked(&priority_queue->lock)); return priority_queue->size; } @@ -344,9 +345,10 @@ priority_queue_length_nolock(struct priority_queue *priority_queue) static inline int priority_queue_length(struct priority_queue *priority_queue) { - LOCK_LOCK(&priority_queue->lock); + lock_node_t node = {}; + lock_lock(&priority_queue->lock, &node); int size = priority_queue_length_nolock(priority_queue); - LOCK_UNLOCK(&priority_queue->lock); + lock_unlock(&priority_queue->lock, &node); return size; } @@ -360,7 +362,7 @@ priority_queue_enqueue_nolock(struct priority_queue *priority_queue, void *value { assert(priority_queue != NULL); assert(value != NULL); - assert(!priority_queue->use_lock || LOCK_IS_LOCKED(&priority_queue->lock)); + assert(!priority_queue->use_lock || lock_is_locked(&priority_queue->lock)); int rc; @@ -386,9 +388,10 @@ priority_queue_enqueue(struct priority_queue *priority_queue, void *value) { int rc; - LOCK_LOCK(&priority_queue->lock); + lock_node_t node = {}; + lock_lock(&priority_queue->lock, &node); rc = priority_queue_enqueue_nolock(priority_queue, value); - LOCK_UNLOCK(&priority_queue->lock); + lock_unlock(&priority_queue->lock, &node); return rc; } @@ -403,7 +406,7 @@ priority_queue_delete_nolock(struct priority_queue *priority_queue, void *value) { assert(priority_queue != NULL); assert(value != NULL); - assert(!priority_queue->use_lock || LOCK_IS_LOCKED(&priority_queue->lock)); + assert(!priority_queue->use_lock || lock_is_locked(&priority_queue->lock)); for (int i = 1; i <= priority_queue->size; i++) { if (priority_queue->items[i] == value) { @@ -427,9 +430,10 @@ priority_queue_delete(struct priority_queue *priority_queue, void *value) { int rc; - LOCK_LOCK(&priority_queue->lock); + lock_node_t node = {}; + lock_lock(&priority_queue->lock, &node); rc = priority_queue_delete_nolock(priority_queue, value); - LOCK_UNLOCK(&priority_queue->lock); + lock_unlock(&priority_queue->lock, &node); return rc; } @@ -468,7 +472,7 @@ priority_queue_top_nolock(struct priority_queue *priority_queue, void **dequeued assert(priority_queue != NULL); assert(dequeued_element != NULL); assert(priority_queue->get_priority_fn != NULL); - assert(!priority_queue->use_lock || LOCK_IS_LOCKED(&priority_queue->lock)); + assert(!priority_queue->use_lock || lock_is_locked(&priority_queue->lock)); int return_code; @@ -495,9 +499,10 @@ priority_queue_top(struct priority_queue *priority_queue, void **dequeued_elemen { int return_code; - LOCK_LOCK(&priority_queue->lock); + lock_node_t node = {}; + lock_lock(&priority_queue->lock, &node); return_code = priority_queue_top_nolock(priority_queue, dequeued_element); - LOCK_UNLOCK(&priority_queue->lock); + lock_unlock(&priority_queue->lock, &node); return return_code; } diff --git a/runtime/include/worker_thread.h b/runtime/include/worker_thread.h index d8be5e5..4065a6c 100644 --- a/runtime/include/worker_thread.h +++ b/runtime/include/worker_thread.h @@ -2,7 +2,6 @@ #include -#include "generic_thread.h" #include "runtime.h" extern thread_local struct arch_context worker_thread_base_context; diff --git a/runtime/src/admissions_control.c b/runtime/src/admissions_control.c index b5bb530..6f857d4 100644 --- a/runtime/src/admissions_control.c +++ b/runtime/src/admissions_control.c @@ -4,6 +4,7 @@ #include "admissions_control.h" #include "debuglog.h" +#include "likely.h" #include "panic.h" #include "runtime.h" diff --git a/runtime/src/admissions_info.c b/runtime/src/admissions_info.c index f8ea090..8ef76bc 100644 --- a/runtime/src/admissions_info.c +++ b/runtime/src/admissions_info.c @@ -24,7 +24,7 @@ admissions_info_initialize(struct admissions_info *admissions_info, uint8_t perc if (unlikely(percentile < 50 || percentile > 99)) panic("Invalid admissions percentile"); admissions_info->percentile = percentile; - admissions_info->control_index = PERF_WINDOW_BUFFER_SIZE * percentile / 100; + admissions_info->control_index = perf_window_capacity * percentile / 100; #ifdef LOG_ADMISSIONS_CONTROL debuglog("Percentile: %u\n", admissions_info->percentile); debuglog("Control Index: %d\n", admissions_info->control_index); @@ -44,12 +44,13 @@ admissions_info_update(struct admissions_info *admissions_info, uint64_t executi #ifdef ADMISSIONS_CONTROL struct perf_window *perf_window = &admissions_info->perf_window; - LOCK_LOCK(&admissions_info->perf_window.lock); + lock_node_t node = {}; + lock_lock(&admissions_info->perf_window.lock, &node); perf_window_add(perf_window, execution_duration); uint64_t estimated_execution = perf_window_get_percentile(perf_window, admissions_info->percentile, admissions_info->control_index); admissions_info->estimate = admissions_control_calculate_estimate(estimated_execution, admissions_info->relative_deadline); - LOCK_UNLOCK(&admissions_info->perf_window.lock); + lock_unlock(&admissions_info->perf_window.lock, &node); #endif } diff --git a/runtime/src/current_sandbox.c b/runtime/src/current_sandbox.c index 792558c..4674495 100644 --- a/runtime/src/current_sandbox.c +++ b/runtime/src/current_sandbox.c @@ -28,8 +28,6 @@ current_sandbox_sleep() struct sandbox *sleeping_sandbox = current_sandbox_get(); assert(sleeping_sandbox != NULL); - generic_thread_dump_lock_overhead(); - switch (sleeping_sandbox->state) { case SANDBOX_RUNNING_SYS: { sandbox_sleep(sleeping_sandbox); @@ -54,8 +52,6 @@ current_sandbox_exit() struct sandbox *exiting_sandbox = current_sandbox_get(); assert(exiting_sandbox != NULL); - generic_thread_dump_lock_overhead(); - switch (exiting_sandbox->state) { case SANDBOX_RETURNED: sandbox_exit_success(exiting_sandbox); @@ -107,7 +103,6 @@ current_sandbox_wasm_trap_handler(int trapno) debuglog("%s", error_message); worker_thread_epoll_remove_sandbox(sandbox); - generic_thread_dump_lock_overhead(); current_sandbox_exit(); assert(0); } @@ -155,7 +150,6 @@ current_sandbox_init() err: debuglog("%s", error_message); worker_thread_epoll_remove_sandbox(sandbox); - generic_thread_dump_lock_overhead(); current_sandbox_exit(); return NULL; } @@ -179,7 +173,6 @@ done: sandbox_set_as_returned(sandbox, SANDBOX_RUNNING_SYS); /* Cleanup connection and exit sandbox */ - generic_thread_dump_lock_overhead(); current_sandbox_exit(); assert(0); err: diff --git a/runtime/src/generic_thread.c b/runtime/src/generic_thread.c deleted file mode 100644 index eb9c453..0000000 --- a/runtime/src/generic_thread.c +++ /dev/null @@ -1,39 +0,0 @@ -#include -#include - -#include "arch/getcycles.h" -#include "debuglog.h" - -extern uint32_t runtime_processor_speed_MHz; -extern uint32_t runtime_quantum_us; - -/* Implemented by listener and workers */ - -thread_local uint64_t generic_thread_lock_duration = 0; -thread_local uint64_t generic_thread_lock_longest = 0; -thread_local uint64_t generic_thread_start_timestamp = 0; - -void -generic_thread_initialize() -{ - generic_thread_start_timestamp = __getcycles(); - generic_thread_lock_longest = 0; - generic_thread_lock_duration = 0; -} - -/** - * Reports lock contention - */ -void -generic_thread_dump_lock_overhead() -{ -#ifndef NDEBUG -#ifdef LOG_LOCK_OVERHEAD - uint64_t duration = __getcycles() - generic_thread_start_timestamp; - debuglog("Locks consumed %lu / %lu cycles, or %f%%\n", generic_thread_lock_duration, duration, - (double)generic_thread_lock_duration / duration * 100); - debuglog("Longest Held Lock was %lu cycles, or %f quantums\n", generic_thread_lock_longest, - (double)generic_thread_lock_longest / ((uint64_t)runtime_processor_speed_MHz * runtime_quantum_us)); -#endif -#endif -} diff --git a/runtime/src/global_request_scheduler_mtds.c b/runtime/src/global_request_scheduler_mtds.c index 09e82cb..db755ed 100644 --- a/runtime/src/global_request_scheduler_mtds.c +++ b/runtime/src/global_request_scheduler_mtds.c @@ -60,7 +60,8 @@ global_request_scheduler_mtds_add(struct sandbox *sandbox) struct tenant_global_request_queue *tgrq = sandbox->tenant->tgrq_requests; - LOCK_LOCK(&global_lock); + lock_node_t node = {}; + lock_lock(&global_lock, &node); struct priority_queue *destination_queue = global_request_scheduler_mtds_default; if (sandbox->tenant->tgrq_requests->mt_class == MT_GUARANTEED) { @@ -84,7 +85,7 @@ global_request_scheduler_mtds_add(struct sandbox *sandbox) // debuglog("Added the TGRQ back to the Global runqueue - %s to Heapify", QUEUE_NAME); } - LOCK_UNLOCK(&global_lock); + lock_unlock(&global_lock, &node); return sandbox; } @@ -124,9 +125,9 @@ global_request_scheduler_mtds_remove_with_mt_class(struct sandbox **removed_sand enum MULTI_TENANCY_CLASS target_mt_class) { int rc = -ENOENT; - ; - LOCK_LOCK(&global_lock); + lock_node_t node = {}; + lock_lock(&global_lock, &node); /* Avoid unnessary locks when the target_deadline is tighter than the head of the Global runqueue */ uint64_t global_guaranteed_deadline = priority_queue_peek(global_request_scheduler_mtds_guaranteed); @@ -180,7 +181,7 @@ global_request_scheduler_mtds_remove_with_mt_class(struct sandbox **removed_sand } done: - LOCK_UNLOCK(&global_lock); + lock_unlock(&global_lock, &node); return rc; } @@ -227,7 +228,7 @@ global_request_scheduler_mtds_initialize() global_tenant_timeout_queue = priority_queue_initialize(RUNTIME_MAX_TENANT_COUNT, false, tenant_timeout_get_priority); - LOCK_INIT(&global_lock); + lock_init(&global_lock); struct global_request_scheduler_config config = { .add_fn = global_request_scheduler_mtds_add, @@ -265,7 +266,8 @@ global_request_scheduler_mtds_promote_lock(struct tenant_global_request_queue *t assert(tgrq != NULL); // assert(priority_queue_length_nolock(tgrq->sandbox_requests) == 0); - LOCK_LOCK(&global_lock); + lock_node_t node = {}; + lock_lock(&global_lock, &node); if (tgrq->mt_class == MT_GUARANTEED) goto done; if (priority_queue_length_nolock(tgrq->sandbox_requests) == 0) goto done; @@ -283,7 +285,7 @@ global_request_scheduler_mtds_promote_lock(struct tenant_global_request_queue *t if (rc == -ENOSPC) panic("Global Guaranteed queue is full!\n"); done: - LOCK_UNLOCK(&global_lock); + lock_unlock(&global_lock, &node); } /* diff --git a/runtime/src/listener_thread.c b/runtime/src/listener_thread.c index 93b887d..2630a95 100644 --- a/runtime/src/listener_thread.c +++ b/runtime/src/listener_thread.c @@ -3,7 +3,6 @@ #include "arch/getcycles.h" #include "global_request_scheduler.h" -#include "generic_thread.h" #include "listener_thread.h" #include "metrics_server.h" #include "module.h" @@ -85,9 +84,9 @@ listener_thread_register_http_session(struct http_session *http) accept_evt.events = EPOLLOUT; http->state = HTTP_SESSION_SEND_RESPONSE_HEADER_BLOCKED; break; - case HTTP_SESSION_SENDING_RESPONSE: + case HTTP_SESSION_SENDING_RESPONSE_BODY: accept_evt.events = EPOLLOUT; - http->state = HTTP_SESSION_SEND_RESPONSE_BLOCKED; + http->state = HTTP_SESSION_SEND_RESPONSE_BODY_BLOCKED; break; default: panic("Invalid HTTP Session State: %d\n", http->state); @@ -272,9 +271,6 @@ on_client_request_received(struct http_session *session) static void on_client_response_header_sending(struct http_session *session) { - assert(session->state = HTTP_SESSION_EXECUTION_COMPLETE); - session->state = HTTP_SESSION_SENDING_RESPONSE_HEADER; - int rc = http_session_send_response_header(session, (void_star_cb)listener_thread_register_http_session); if (likely(rc == 0)) { on_client_response_body_sending(session); @@ -310,6 +306,8 @@ on_client_response_body_sending(struct http_session *session) static void on_client_response_sent(struct http_session *session) { + assert(session->state = HTTP_SESSION_SENT_RESPONSE_BODY); + /* Terminal State Logging for Http Session */ session->response_sent_timestamp = __getcycles(); http_session_perf_log_print_entry(session); @@ -388,7 +386,7 @@ on_client_socket_epoll_event(struct epoll_event *evt) assert((evt->events & EPOLLOUT) == EPOLLOUT); on_client_response_header_sending(session); break; - case HTTP_SESSION_SEND_RESPONSE_BLOCKED: + case HTTP_SESSION_SEND_RESPONSE_BODY_BLOCKED: assert((evt->events & EPOLLOUT) == EPOLLOUT); on_client_response_body_sending(session); break; @@ -445,7 +443,6 @@ listener_thread_main(void *dummy) on_client_socket_epoll_event(&epoll_events[i]); } } - generic_thread_dump_lock_overhead(); } panic("Listener thread unexpectedly broke loop\n"); diff --git a/runtime/src/main.c b/runtime/src/main.c index 6932428..2f4cd3c 100644 --- a/runtime/src/main.c +++ b/runtime/src/main.c @@ -289,12 +289,6 @@ log_compiletime_config() pretty_print_key_disabled("Log HTTP Parser"); #endif -#ifdef LOG_LOCK_OVERHEAD - pretty_print_key_enabled("Log Lock Overhead"); -#else - pretty_print_key_disabled("Log Lock Overhead"); -#endif - #ifdef LOG_TENANT_LOADING pretty_print_key_enabled("Log Tenant Loading"); #else diff --git a/tests/cmu-sod/.gitignore b/tests/cmu-sod/.gitignore new file mode 100644 index 0000000..019d491 --- /dev/null +++ b/tests/cmu-sod/.gitignore @@ -0,0 +1 @@ +out.png diff --git a/tests/cmu-sod/0_depth.png b/tests/cmu-sod/0_depth.png new file mode 100644 index 0000000..242a89b Binary files /dev/null and b/tests/cmu-sod/0_depth.png differ diff --git a/tests/cmu-sod/0_rgb.png b/tests/cmu-sod/0_rgb.png new file mode 100644 index 0000000..84da58a Binary files /dev/null and b/tests/cmu-sod/0_rgb.png differ diff --git a/tests/cmu-sod/Makefile b/tests/cmu-sod/Makefile new file mode 100644 index 0000000..a0ca4b5 --- /dev/null +++ b/tests/cmu-sod/Makefile @@ -0,0 +1,20 @@ +SLEDGE_BINARY_DIR=../../runtime/bin +HOSTNAME=localhost + +default: run + +clean: + rm -rf res/* + +run: + LD_LIBRARY_PATH=${SLEDGE_BINARY_DIR} ${SLEDGE_BINARY_DIR}/sledgert spec.json + +debug: + SLEDGE_DISABLE_PREEMPTION=true SLEDGE_NWORKERS=1 LD_LIBRARY_PATH=${SLEDGE_BINARY_DIR} gdb ${SLEDGE_BINARY_DIR}/sledgert --eval-command="run spec.json" + +valgrind: + SLEDGE_DISABLE_PREEMPTION=true SLEDGE_NWORKERS=1 LD_LIBRARY_PATH=${SLEDGE_BINARY_DIR} valgrind --leak-check=full --max-stackframe=11150456 --run-libc-freeres=no --run-cxx-freeres=no ${SLEDGE_BINARY_DIR}/sledgert spec.json + +.PHONY: client +client: + cat ./0_depth.png | http "${HOSTNAME}:10000/depth_to_xyz" > ./out.png diff --git a/tests/cmu-sod/expected_result.png b/tests/cmu-sod/expected_result.png new file mode 100644 index 0000000..48198ea Binary files /dev/null and b/tests/cmu-sod/expected_result.png differ diff --git a/tests/cmu-sod/spec.json b/tests/cmu-sod/spec.json new file mode 100644 index 0000000..253a3d6 --- /dev/null +++ b/tests/cmu-sod/spec.json @@ -0,0 +1,18 @@ +[ + { + "name": "cmu", + "port": 10000, + "replenishment-period-us": 0, + "max-budget-us": 0, + "routes": [ + { + "route": "/depth_to_xyz", + "path": "depth_to_xyz.wasm.so", + "expected-execution-us": 5000, + "relative-deadline-us": 360000, + "http-resp-size": 5335057, + "http-resp-content-type": "img/png" + } + ] + } +] diff --git a/tests/empty/concurrency/run.sh b/tests/empty/concurrency/run.sh index 378f0fe..2816770 100755 --- a/tests/empty/concurrency/run.sh +++ b/tests/empty/concurrency/run.sh @@ -38,16 +38,16 @@ run_samples() { # Scrape the perf window size from the source if possible # TODO: Make a util function local -r perf_window_path="$(path_join "$__run_sh__base_path" ../../../runtime/include/perf_window_t.h)" - local -i perf_window_buffer_size - if ! perf_window_buffer_size=$(grep "#define PERF_WINDOW_BUFFER_SIZE" < "$perf_window_path" | cut -d\ -f3); then - printf "Failed to scrape PERF_WINDOW_BUFFER_SIZE from ../../include/perf_window.h\n" + local -i perf_window_capacity + if ! perf_window_capacity=$(grep "perf_window_capacity =" < "$perf_window_path" | cut -d\ -f3); then + printf "Failed to scrape perf_window_capacity from ../../include/perf_window.h\n" printf "Defaulting to 16\n" - perf_window_buffer_size=16 + perf_window_capacity=16 fi - local -ir perf_window_buffer_size + local -ir perf_window_capacity printf "Running Samples: " - hey -disable-compression -disable-keepalive -disable-redirects -n "$perf_window_buffer_size" -c "$perf_window_buffer_size" -q 200 -cpus 3 -o csv -m GET "http://${hostname}:10000" 1> /dev/null 2> /dev/null || { + hey -disable-compression -disable-keepalive -disable-redirects -n "$perf_window_capacity" -c "$perf_window_capacity" -q 200 -cpus 3 -o csv -m GET "http://${hostname}:10000/empty" 1> /dev/null 2> /dev/null || { printf "[ERR]\n" panic "samples failed" return 1 @@ -79,7 +79,7 @@ run_experiments() { printf "Running Experiments:\n" for conn in ${concurrency[*]}; do printf "\t%d Concurrency: " "$conn" - hey -disable-compression -disable-keepalive -disable-redirects -n "$iterations" -c "$conn" -cpus 2 -o csv -m GET "http://$hostname:10000" > "$results_directory/con$conn.csv" 2> /dev/null || { + hey -disable-compression -disable-keepalive -disable-redirects -n "$iterations" -c "$conn" -cpus 2 -o csv -m GET "http://$hostname:10000/empty" > "$results_directory/con$conn.csv" 2> /dev/null || { printf "[ERR]\n" panic "experiment failed" return 1 diff --git a/tests/fibonacci/bimodal/run.sh b/tests/fibonacci/bimodal/run.sh index f64a167..c95b694 100755 --- a/tests/fibonacci/bimodal/run.sh +++ b/tests/fibonacci/bimodal/run.sh @@ -41,22 +41,22 @@ run_samples() { # Scrape the perf window size from the source if possible # TODO: Make a util function local -r perf_window_path="$(path_join "$__run_sh__base_path" ../../../runtime/include/perf_window_t.h)" - local -i perf_window_buffer_size - if ! perf_window_buffer_size=$(grep "#define PERF_WINDOW_BUFFER_SIZE" < "$perf_window_path" | cut -d\ -f3); then - printf "Failed to scrape PERF_WINDOW_BUFFER_SIZE from ../../../runtime/include/perf_window.h\n" + local -i perf_window_capacity + if ! perf_window_capacity=$(grep "perf_window_capacity =" < "$perf_window_path" | cut -d\ -f3); then + printf "Failed to scrape perf_window_capacity from ../../../runtime/include/perf_window.h\n" printf "Defaulting to 16\n" - perf_window_buffer_size=16 + perf_window_capacity=16 fi - local -ir perf_window_buffer_size + local -ir perf_window_capacity printf "Running Samples: " - hey -disable-compression -disable-keepalive -disable-redirects -n "$perf_window_buffer_size" -c "$perf_window_buffer_size" -cpus 3 -t 0 -o csv -m GET -d "40\n" "http://${hostname}:10010/fib2" 1> /dev/null 2> /dev/null || { + hey -disable-compression -disable-keepalive -disable-redirects -n "$perf_window_capacity" -c "$perf_window_capacity" -cpus 3 -t 0 -o csv -m GET -d "40\n" "http://${hostname}:10010/fib2" 1> /dev/null 2> /dev/null || { printf "[ERR]\n" panic "fib40 samples failed with $?" return 1 } - hey -disable-compression -disable-keepalive -disable-redirects -n "$perf_window_buffer_size" -c "$perf_window_buffer_size" -cpus 3 -t 0 -o csv -m GET -d "10\n" "http://${hostname}:100010/fib" 1> /dev/null 2> /dev/null || { + hey -disable-compression -disable-keepalive -disable-redirects -n "$perf_window_capacity" -c "$perf_window_capacity" -cpus 3 -t 0 -o csv -m GET -d "10\n" "http://${hostname}:100010/fib" 1> /dev/null 2> /dev/null || { printf "[ERR]\n" panic "fib10 samples failed with $?" return 1 diff --git a/tests/workload_mix/run.sh b/tests/workload_mix/run.sh index 4079276..86e54b9 100755 --- a/tests/workload_mix/run.sh +++ b/tests/workload_mix/run.sh @@ -38,22 +38,22 @@ run_samples() { # Scrape the perf window size from the source if possible # TODO: Make a util function local -r perf_window_path="$(path_join "$__run_sh__base_path" ../../runtime/include/perf_window_t.h)" - local -i perf_window_buffer_size - if ! perf_window_buffer_size=$(grep "#define PERF_WINDOW_BUFFER_SIZE" < "$perf_window_path" | cut -d\ -f3); then - printf "Failed to scrape PERF_WINDOW_BUFFER_SIZE from ../../runtime/include/perf_window.h\n" + local -i perf_window_capacity + if ! perf_window_capacity=$(grep "perf_window_capacity =" < "$perf_window_path" | cut -d\ -f3); then + printf "Failed to scrape perf_window_capacity from ../../runtime/include/perf_window.h\n" printf "Defaulting to 16\n" - perf_window_buffer_size=16 + perf_window_capacity=16 fi - local -ir perf_window_buffer_size + local -ir perf_window_capacity printf "Running Samples: " - hey -disable-compression -disable-keepalive -disable-redirects -n "$perf_window_buffer_size" -c "$perf_window_buffer_size" -cpus 3 -t 0 -o csv -m GET -d "40\n" "http://${hostname}:10000/fibonacci_10" 1> /dev/null 2> /dev/null || { + hey -disable-compression -disable-keepalive -disable-redirects -n "$perf_window_capacity" -c "$perf_window_capacity" -cpus 3 -t 0 -o csv -m GET -d "40\n" "http://${hostname}:10000/fibonacci_10" 1> /dev/null 2> /dev/null || { printf "[ERR]\n" panic "fibonacci_40 samples failed with $?" return 1 } - hey -disable-compression -disable-keepalive -disable-redirects -n "$perf_window_buffer_size" -c "$perf_window_buffer_size" -cpus 3 -t 0 -o csv -m GET -d "10\n" "http://${hostname}:10000/fibonacci_10" 1> /dev/null 2> /dev/null || { + hey -disable-compression -disable-keepalive -disable-redirects -n "$perf_window_capacity" -c "$perf_window_capacity" -cpus 3 -t 0 -o csv -m GET -d "10\n" "http://${hostname}:10000/fibonacci_10" 1> /dev/null 2> /dev/null || { printf "[ERR]\n" panic "fibonacci_10 samples failed with $?" return 1