Compare commits

...

8 Commits
main ... tree

@ -25,5 +25,5 @@
"workspaceMount": "source=${localWorkspaceFolder},target=/sledge,type=bind,consistency=cached", "workspaceMount": "source=${localWorkspaceFolder},target=/sledge,type=bind,consistency=cached",
"workspaceFolder": "/sledge", "workspaceFolder": "/sledge",
"postCreateCommand": "make -C /sledge install && make -B -C /sledge/runtime/tests clean all", "postCreateCommand": "make -C /sledge install && make -B -C /sledge/runtime/tests clean all",
"containerUser": "dev", "containerUser": "dev"
} }

@ -1,3 +1,2 @@
LD_LIBRARY_PATH=/home/hai/sledge-serverless-framework/runtime/bin LD_LIBRARY_PATH=/home/hai/sledge-serverless-framework/runtime/bin
SLEDGE_SCHEDULER=EDF SLEDGE_SCHEDULER=EDF
SLEDGE_SANDBOX_PERF_LOG=/home/hai/sledge-serverless-framework/debuglog.txt

129
.vscode/launch.json vendored

@ -1,52 +1,85 @@
{ {
// Use IntelliSense to learn about possible attributes. "version": "0.2.0",
// Hover to view descriptions of existing attributes. "configurations": [
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 {
"version": "0.2.0", "name": "Hyde",
"configurations": [ "type": "cppdbg",
{ "request": "launch",
"name": "Hyde", "program": "${workspaceFolder}/runtime/bin/sledgert",
"type": "cppdbg", "args": [
"request": "launch", "${workspaceFolder}/runtime/experiments/applications/ocr/hyde/spec.json"
"program": "${workspaceFolder}/runtime/bin/sledgert", ],
"args": [ "stopAtEntry": false,
"${workspaceFolder}/runtime/experiments/applications/ocr/hyde/spec.json" "cwd": "${workspaceFolder}",
], "environment": [
"stopAtEntry": false, {
"cwd": "${workspaceFolder}", "name": "SLEDGE_SANDBOX_PERF_LOG",
"environment": [], "value": "${workspaceFolder}/debug.log"
"externalConsole": false, }
"MIMode": "gdb", ],
"envFile": "${workspaceFolder}/.env", "externalConsole": false,
"setupCommands": [ "MIMode": "gdb",
{ "envFile": "${workspaceFolder}/.env",
"description": "Enable pretty-printing for gdb", "sourceFileMap": {
"text": "-enable-pretty-printing", "/sledge/runtime": "${workspaceFolder}/runtime"
"ignoreFailures": true
}
]
}, },
{ "setupCommands": [
"name": "Preemption", {
"type": "cppdbg", "description": "Enable pretty-printing for gdb",
"request": "launch", "text": "-enable-pretty-printing",
"program": "${workspaceFolder}/runtime/bin/sledgert", "ignoreFailures": true
"args": [ }
"${workspaceFolder}/runtime/experiments/preemption/spec.json" ]
], },
"stopAtEntry": false, {
"cwd": "${workspaceFolder}", "name": "Preemption",
"environment": [], "type": "cppdbg",
"externalConsole": false, "request": "launch",
"MIMode": "gdb", "program": "${workspaceFolder}/runtime/bin/sledgert",
"envFile": "${workspaceFolder}/.env", "args": [
"setupCommands": [ "${workspaceFolder}/runtime/tests/test_multiple_image_processing4.json"
{ ],
"description": "Enable pretty-printing for gdb", "stopAtEntry": false,
"text": "-enable-pretty-printing", "cwd": "${workspaceFolder}",
"ignoreFailures": true "environment": [],
} "externalConsole": false,
] "MIMode": "gdb",
} "sourceFileMap": {
"/sledge/runtime": "${workspaceFolder}/runtime"
},
"envFile": "${workspaceFolder}/.env",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
},
{
"name": "tree",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/runtime/bin/sledgert",
"args": [
"${workspaceFolder}/runtime/tests/tree.json"
],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"sourceFileMap": {
"/sledge/runtime": "${workspaceFolder}/runtime"
},
"envFile": "${workspaceFolder}/.env",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
] ]
} }

@ -95,7 +95,11 @@
"compare": "c", "compare": "c",
"cstdint": "c", "cstdint": "c",
"format": "c", "format": "c",
"jsmn.h": "c" "jsmn.h": "c",
"priority_queue.h": "c",
"hash.h": "c",
"lock.h": "c",
"span": "cpp"
}, },
"files.exclude": { "files.exclude": {
"**/.git": true, "**/.git": true,

@ -0,0 +1,88 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TABLE_SIZE 100
typedef struct Node {
int key;
char value[256];
struct Node* next;
} Node;
typedef struct Edge {
Node* from;
Node* to;
double cost;
struct Edge* next;
} Edge;
typedef struct Graph {
Node* nodes[TABLE_SIZE];
Edge* edges[TABLE_SIZE];
} Graph;
unsigned int hash(int key) {
return key % TABLE_SIZE;
}
void insertNode(Graph* g, int key, const char* value) {
unsigned int index = hash(key);
Node* new_node = (Node*) malloc(sizeof(Node));
if (new_node) {
new_node->key = key;
strcpy(new_node->value, value);
new_node->next = g->nodes[index];
g->nodes[index] = new_node;
}
}
Node* findNode(Graph* g, int key) {
unsigned int index = hash(key);
Node* node = g->nodes[index];
while (node) {
if (node->key == key)
return node;
node = node->next;
}
return NULL;
}
void insertEdge(Graph* g, int fromKey, int toKey, double cost) {
Node* fromNode = findNode(g, fromKey);
Node* toNode = findNode(g, toKey);
if (fromNode && toNode) {
unsigned int index = hash(fromKey);
Edge* new_edge = (Edge*) malloc(sizeof(Edge));
if (new_edge) {
new_edge->from = fromNode;
new_edge->to = toNode;
new_edge->cost = cost;
new_edge->next = g->edges[index];
g->edges[index] = new_edge;
}
}
}
void initGraph(Graph* g) {
for (int i = 0; i < TABLE_SIZE; i++) {
g->nodes[i] = NULL;
g->edges[i] = NULL;
}
}
int main() {
Graph g;
initGraph(&g);
insertNode(&g, 1, "Node 1");
insertNode(&g, 2, "Node 2");
insertEdge(&g, 1, 2, 0.5);
Node* n = findNode(&g, 1);
if (n) {
printf("Found node: %s\n", n->value);
}
return 0;
}

@ -10,10 +10,10 @@ PAGE_SIZE := $(shell getconf PAGESIZE)
# Compiler Settings # Compiler Settings
CC=clang CC=clang
CC_OPTIONS = -O3 -flto -g -pthread -D_GNU_SOURCE # CC_OPTIONS = -O3 -flto -g -pthread -D_GNU_SOURCE
# CC_OPTIONS for Debugging # CC_OPTIONS for Debugging
# CC_OPTIONS = -O0 -g -pthread -D_GNU_SOURCE CC_OPTIONS = -O0 -g -pthread -D_GNU_SOURCE
# CFI Sanitizer # CFI Sanitizer
# CC_OPTIONS = -O0 -g -pthread -D_GNU_SOURCE -flto -fvisibility=default -fsanitize=cfi # CC_OPTIONS = -O0 -g -pthread -D_GNU_SOURCE -flto -fvisibility=default -fsanitize=cfi
@ -59,7 +59,7 @@ CFLAGS += -DLOG_TO_FILE
# CFLAGS += -DLOG_PREEMPTION # CFLAGS += -DLOG_PREEMPTION
# CFLAGS += -DLOG_MODULE_LOADING # CFLAGS += -DLOG_MODULE_LOADING
# CFLAGS += -DOPT_AVOID_GLOBAL_QUEUE # CFLAGS += -DOPT_AVOID_GLOBAL_QUEUE
# CFLAGS += -DLOG_RUNTIME_FILE_LOG CFLAGS += -DLOG_RUNTIME_FILE_LOG
CFLAGS += -DLOG_RUNTIME_MEM_LOG CFLAGS += -DLOG_RUNTIME_MEM_LOG
# This dumps per module *.csv files containing the cycle a sandbox has been in RUNNING when each # This dumps per module *.csv files containing the cycle a sandbox has been in RUNNING when each

@ -0,0 +1,53 @@
import unittest,importlib,BeautifulReport
import cffi
def load():
with open("/home/hai/sledge-serverless-framework/runtime/include/hash.h", "r") as f:
inc = ""
for line in f:
if not line.strip().startswith('#'):
inc += line
src = open("/home/hai/sledge-serverless-framework/runtime/Utest_py/hash.c").read()
builder = cffi.FFI()
builder.cdef(inc)
builder.set_source("hashlib",src)
builder.compile()
md = importlib.import_module("hashlib")
return md.lib
md = load()
class HashTableTestCase(unittest.TestCase):
def test_case1(self):
'''
测试添加和查找功能
'''
table = md.create_table()
md.add_item(table, b"key1", "Hello World")
value = md.find_value(table, b"key1")
self.assertEqual(value, "Hello World")
print('Value for "key1":', value)
def test_case2(self):
'''
测试查找不存在的键
'''
table = md.create_table()
value = md.find_value(table, b"nonexistent")
self.assertIsNone(value)
print('Value for "nonexistent":', value)
def test_case3(self):
# 确保每个测试后表被释放
md.free_table(self.table)
sut = unittest.TestSuite()
sut.addTest(unittest.makeSuite(HashTableTestCase))
run = BeautifulReport.BeautifulReport(sut)
run.report(filename="test.html",description="单元测试")

Binary file not shown.

@ -0,0 +1,49 @@
// hash_test.c
#include "../include/hash.h"
#include <stdio.h>
typedef struct test
{
char *name;
}test;
int main(int argc, char *argv[]) {
test *test1 = malloc(sizeof(test));
test *test2 = malloc(sizeof(test));
test1->name = "test1";
test2->name = "test2";
HashTable *myTable = create_table();
add_item(myTable, "key1", test1);
add_item(myTable, "key2", test2);
char *input = argv[1];
test *value = find_value(myTable, input);
if (value) {
printf("Test Passed: %s\n", value->name);
} else {
printf("Test Failed: Key not found.\n");
}
remove_item(myTable, "key1");
printf("remove key1.\n");
test *value2 = find_value(myTable, input);
if (value2) {
printf("Test Passed: %s\n", value2->name);
} else {
printf("Test Failed: Key not found.\n");
}
add_item(myTable, "key1", test1);
test *value4 = find_value(myTable, "key1");
if (value4) {
printf("Test Passed: %s\n", value4->name);
} else {
printf("Test Failed: Key not found.\n");
}
test *value3 = find_value(myTable, "key2");
if (value3) {
printf("Test Passed: %s\n", value3->name);
} else {
printf("Test Failed: Key not found.\n");
}
free(test1);
free(test2);
free_table(myTable);
return 0;
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,144 @@
#ifndef HASH_H
#define HASH_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <pthread.h>
#define TABLE_SIZE 32 // the size of hash table
#define MAX_KEY_LENGTH 32 // the maximum length of key
typedef struct {
char key[MAX_KEY_LENGTH];
void *value;
int is_deleted; // Flag to mark items as deleted
} HashItem;
typedef struct {
HashItem **items;
pthread_mutex_t lock;
} HashTable;
static inline unsigned long
hash_function(const char *str) {
unsigned long i = 0;
for (int j = 0; str[j]; j++)
i += str[j];
return i % TABLE_SIZE;
}
static inline HashTable
*create_table() {
HashTable *table = (HashTable *)malloc(sizeof(HashTable));
if (!table) {
fprintf(stderr, "Failed to allocate memory for hash table struct.\n");
return NULL;
}
table->items = (HashItem **)malloc(sizeof(HashItem*) * TABLE_SIZE);
if (!table->items) {
fprintf(stderr, "Failed to allocate memory for items.\n");
free(table); // Free the table if item allocation fails
return NULL;
}
pthread_mutex_init(&table->lock, NULL);
for (int i = 0; i < TABLE_SIZE; i++) {
table->items[i] = NULL;
}
return table;
}
static inline void
add_item(HashTable *table, const char *key, void *value) {
assert(table != NULL);
assert(key != NULL);
assert(value != NULL);
pthread_mutex_lock(&table->lock);
unsigned long index = hash_function(key);
HashItem *item = malloc(sizeof(HashItem));
if (!item) {
fprintf(stderr, "Failed to allocate memory for a new item.\n");
pthread_mutex_unlock(&table->lock);
return;
}
strcpy(item->key, key);
item->value = value;
item->is_deleted = 0;
while (table->items[index] != NULL && !table->items[index]->is_deleted && strcmp(table->items[index]->key, key) != 0) {
index = (index + 1) % TABLE_SIZE;
}
free(table->items[index]); // Free the existing item if overwriting
table->items[index] = item;
pthread_mutex_unlock(&table->lock);
}
static inline void
remove_item(HashTable *table, const char *key) {
assert(table != NULL);
assert(key != NULL);
pthread_mutex_lock(&table->lock);
unsigned long index = hash_function(key);
while (table->items[index] != NULL && strcmp(table->items[index]->key, key) != 0) {
index = (index + 1) % TABLE_SIZE;
}
if (table->items[index] != NULL) {
table->items[index]->is_deleted = 1; // Mark as deleted
}
pthread_mutex_unlock(&table->lock);
}
static inline void
*find_value(HashTable *table, const char *key) {
assert(table != NULL);
assert(key != NULL);
pthread_mutex_lock(&table->lock);
unsigned long index = hash_function(key);
int count = 0;
while (table->items[index] != NULL && count < TABLE_SIZE && (table->items[index]->is_deleted || strcmp(table->items[index]->key, key) != 0)) {
index = (index + 1) % TABLE_SIZE;
count++;
}
if (table->items[index] == NULL || table->items[index]->is_deleted)
{
pthread_mutex_unlock(&table->lock);
return NULL;
}
else {
pthread_mutex_unlock(&table->lock);
return table->items[index]->value;
}
}
static inline void
free_table(HashTable *table) {
assert(table != NULL);
pthread_mutex_lock(&table->lock);
for (int i = 0; i < TABLE_SIZE; i++) {
if (table->items[i] != NULL) {
free(table->items[i]); // Free each item
}
}
free(table->items);
free(table);
pthread_mutex_unlock(&table->lock);
pthread_mutex_destroy(&table->lock);
}
#endif

@ -85,9 +85,9 @@ struct module {
/* the left and right children module in the tree */ /* the left and right children module in the tree */
struct module *left_module; struct module *left_module;
struct module *right_module; struct module *right_module;
struct module *parent_module;
/* parent module or not?*/ /* parent module or not?*/
bool is_parent; bool is_sandboxcreate;
}; };
/************************* /*************************

@ -226,7 +226,7 @@ sandbox_mem_print_perf(struct sandbox *sandbox)
uint64_t returned_us = sandbox->returned_duration / runtime_processor_speed_MHz; uint64_t returned_us = sandbox->returned_duration / runtime_processor_speed_MHz;
//if (sandbox->module->next_module == NULL) { //if (sandbox->module->next_module == NULL) {
if(sandbox->module->is_parent) { if(sandbox->module->parent_module == NULL) {
uint64_t total_time = (sandbox->completion_timestamp - sandbox->request_arrival_timestamp) / runtime_processor_speed_MHz; uint64_t total_time = (sandbox->completion_timestamp - sandbox->request_arrival_timestamp) / runtime_processor_speed_MHz;
bool miss_deadline = sandbox->completion_timestamp > sandbox->absolute_deadline ? true : false; bool miss_deadline = sandbox->completion_timestamp > sandbox->absolute_deadline ? true : false;
uint64_t delayed_us = (sandbox->completion_timestamp - sandbox->absolute_deadline) uint64_t delayed_us = (sandbox->completion_timestamp - sandbox->absolute_deadline)

@ -6,6 +6,7 @@
#include <stdint.h> #include <stdint.h>
#include <sys/socket.h> #include <sys/socket.h>
#include "debuglog.h" #include "debuglog.h"
#include "deque.h" #include "deque.h"
#include "http_total.h" #include "http_total.h"
@ -26,6 +27,7 @@ struct sandbox_request {
uint64_t last_update_timestamp; /* cycles */ uint64_t last_update_timestamp; /* cycles */
uint64_t remaining_slack; /* cycles */ uint64_t remaining_slack; /* cycles */
char * previous_function_output; char * previous_function_output;
char * previous_function_output2;
ssize_t output_length; ssize_t output_length;
ssize_t previous_request_length; ssize_t previous_request_length;
/* /*
@ -74,7 +76,7 @@ static inline struct sandbox_request *
sandbox_request_allocate(struct module *module, bool request_from_outside, ssize_t request_length, sandbox_request_allocate(struct module *module, bool request_from_outside, ssize_t request_length,
char *arguments, int socket_descriptor, const struct sockaddr *socket_address, char *arguments, int socket_descriptor, const struct sockaddr *socket_address,
uint64_t request_arrival_timestamp, uint64_t enqueue_timestamp, uint64_t remaining_slack, uint64_t request_arrival_timestamp, uint64_t enqueue_timestamp, uint64_t remaining_slack,
uint64_t admissions_estimate, char *previous_function_output, ssize_t output_length) uint64_t admissions_estimate, char *previous_function_output, char * previous_function_output2, ssize_t output_length)
{ {
struct sandbox_request *sandbox_request = (struct sandbox_request *)malloc(sizeof(struct sandbox_request)); struct sandbox_request *sandbox_request = (struct sandbox_request *)malloc(sizeof(struct sandbox_request));
assert(sandbox_request); assert(sandbox_request);
@ -91,6 +93,7 @@ sandbox_request_allocate(struct module *module, bool request_from_outside, ssize
sandbox_request->enqueue_timestamp = enqueue_timestamp; sandbox_request->enqueue_timestamp = enqueue_timestamp;
sandbox_request->absolute_deadline = request_arrival_timestamp + module->relative_deadline; sandbox_request->absolute_deadline = request_arrival_timestamp + module->relative_deadline;
sandbox_request->previous_function_output = previous_function_output; sandbox_request->previous_function_output = previous_function_output;
sandbox_request->previous_function_output2 = previous_function_output2;
sandbox_request->output_length = output_length; sandbox_request->output_length = output_length;
sandbox_request->previous_request_length = request_length; sandbox_request->previous_request_length = request_length;
sandbox_request->last_update_timestamp = enqueue_timestamp; sandbox_request->last_update_timestamp = enqueue_timestamp;

@ -33,6 +33,7 @@ struct sandbox {
uint64_t id; uint64_t id;
bool request_from_outside; bool request_from_outside;
char * previous_function_output; /* the output of the previous function */ char * previous_function_output; /* the output of the previous function */
char * previous_function_output2;
ssize_t output_length; /* the length of previous_function_output */ ssize_t output_length; /* the length of previous_function_output */
ssize_t previous_request_length; /* the length of previous request */ ssize_t previous_request_length; /* the length of previous request */
sandbox_state_t state; sandbox_state_t state;

@ -8,8 +8,10 @@
#include "scheduler.h" #include "scheduler.h"
#include "module.h" #include "module.h"
#include "software_interrupt.h" #include "software_interrupt.h"
#include "hash.h"
extern uint64_t system_start_timestamp; extern uint64_t system_start_timestamp;
#define OUPUT_MAX 20;
__thread struct sandbox *worker_thread_current_sandbox = NULL; __thread struct sandbox *worker_thread_current_sandbox = NULL;
@ -70,7 +72,11 @@ current_sandbox_start(void)
char *error_message = ""; char *error_message = "";
sandbox_initialize_stdio(sandbox); sandbox_initialize_stdio(sandbox);
struct module * next_module = sandbox->module->next_module; //struct module * next_module = sandbox->module->next_module;
struct module * next_module = sandbox->module->parent_module;
static HashTable *sandboxes_request_table = NULL;
if (sandboxes_request_table == NULL) sandboxes_request_table = create_table();
/* /*
* Add the client fd to epoll if it is the first or last sandbox in the chain because they * Add the client fd to epoll if it is the first or last sandbox in the chain because they
@ -120,27 +126,69 @@ current_sandbox_start(void)
} else if (next_module != NULL) { } else if (next_module != NULL) {
/* Generate a new request, copy the current sandbox's output to the next request's buffer, and put it to the global queue */ /* Generate a new request, copy the current sandbox's output to the next request's buffer, and put it to the global queue */
ssize_t output_length = sandbox->request_response_data_length - sandbox->request_length; ssize_t output_length = sandbox->request_response_data_length - sandbox->request_length;
char * pre_func_output = (char *)malloc(output_length); char * pre_func_output = NULL;
if (!pre_func_output) { char * pre_func_output2 = NULL;
if (strcmp(next_module->left_module->name, sandbox->module->name) == 0)
{
pre_func_output = (char *)malloc(output_length);
if (!pre_func_output) {
fprintf(stderr, "Failed to allocate memory for the previous output: %s\n", strerror(errno)); fprintf(stderr, "Failed to allocate memory for the previous output: %s\n", strerror(errno));
goto err; goto err;
}; };
memcpy(pre_func_output, sandbox->request_response_data + sandbox->request_length, output_length); memcpy(pre_func_output, sandbox->request_response_data + sandbox->request_length, output_length);
}else
{
pre_func_output2 = (char *)malloc(output_length);
if (!pre_func_output2) {
fprintf(stderr, "Failed to allocate memory for the previous output: %s\n", strerror(errno));
goto err;
};
memcpy(pre_func_output2, sandbox->request_response_data + sandbox->request_length, output_length);
}
uint64_t enqueue_timestamp = __getcycles(); uint64_t enqueue_timestamp = __getcycles();
//uint64_t current_rs = enqueue_timestamp - system_start_timestamp; //uint64_t current_rs = enqueue_timestamp - system_start_timestamp;
//mem_log("time %lu request id:%d executing, name:%s remaining slack %lu\n", current_rs, //mem_log("time %lu request id:%d executing, name:%s remaining slack %lu\n", current_rs,
// sandbox->id, sandbox->module->name, sandbox->remaining_slack); // sandbox->id, sandbox->module->name, sandbox->remaining_slack);
struct sandbox_request *sandbox_request = struct sandbox_request *sandbox_request = NULL;
sandbox_request_allocate(next_module, false, sandbox->request_length, static bool left_output_flag = false;
next_module->name, sandbox->client_socket_descriptor, if (next_module->is_sandboxcreate == false)
(const struct sockaddr *)&sandbox->client_address, {
sandbox->request_arrival_timestamp, enqueue_timestamp, sandbox_request =
sandbox->remaining_slack, true, pre_func_output, output_length); sandbox_request_allocate(next_module, false, sandbox->request_length,
/* TODO: All sandboxs in the chain share the same request id, but sandbox_request_allocate() next_module->name, sandbox->client_socket_descriptor,
* will busy-wait to generate an unique id, should we optimize it here? (const struct sockaddr *)&sandbox->client_address,
*/ sandbox->request_arrival_timestamp, enqueue_timestamp,
sandbox_request->id = sandbox->id; sandbox->remaining_slack, true, pre_func_output, pre_func_output2, output_length);
sandbox_request->id = sandbox->id;
add_item(sandboxes_request_table, next_module->name, sandbox_request);
if (pre_func_output != NULL) left_output_flag = true;
else left_output_flag = false;
/*change the flag*/
next_module->is_sandboxcreate = true;
}else
{
sandbox_request = find_value(sandboxes_request_table, next_module->name);
assert(sandbox_request);
if (left_output_flag == true)
{
sandbox_request->previous_function_output2 = pre_func_output2;
}else
{
sandbox_request->previous_function_output = pre_func_output;
}
ssize_t combined_length = sandbox_request->output_length + output_length + 3;
remove_item(sandboxes_request_table, next_module->name);
char *combined_output = (char *)malloc(combined_length);
if (!combined_output) {
fprintf(stderr, "Failed to allocate memory for the combined output: %s\n", strerror(errno));
goto err;
}
strcpy(combined_output, sandbox_request->previous_function_output);
strcat(combined_output, "+");
strcat(combined_output, sandbox_request->previous_function_output2);
sandbox->output_length = combined_length;
#ifdef OPT_AVOID_GLOBAL_QUEUE #ifdef OPT_AVOID_GLOBAL_QUEUE
/* TODO: The running time of the current sandbox contains the next sandbox's initialization time, does it matter? */ /* TODO: The running time of the current sandbox contains the next sandbox's initialization time, does it matter? */
if (sandbox->absolute_deadline == sandbox_request->absolute_deadline) { if (sandbox->absolute_deadline == sandbox_request->absolute_deadline) {
@ -160,12 +208,19 @@ current_sandbox_start(void)
#else #else
/* Add to the Global Sandbox Request Scheduler */ /* Add to the Global Sandbox Request Scheduler */
global_request_scheduler_add(sandbox_request); global_request_scheduler_add(sandbox_request);
if (sandbox_send_response(sandbox) < 0) {
error_message = "Unable to build and send client response\n";
goto err;
};
next_module->is_sandboxcreate = false;
}
#endif #endif
/* Remove the client fd from epoll if it is the first sandbox in the chain */ /* Remove the client fd from epoll if it is the first sandbox in the chain */
if (sandbox->request_from_outside) { if (sandbox->request_from_outside) {
sandbox_remove_from_epoll(sandbox); sandbox_remove_from_epoll(sandbox);
} }
sandbox_set_as_returned(sandbox, SANDBOX_RUNNING); sandbox_set_as_returned(sandbox, SANDBOX_RUNNING);
} else { } else {
/* Retrieve the result, construct the HTTP response, and send to client */ /* Retrieve the result, construct the HTTP response, and send to client */
if (sandbox_send_response(sandbox) < 0) { if (sandbox_send_response(sandbox) < 0) {

@ -180,7 +180,8 @@ listener_thread_main(void *dummy)
struct module * next_module = module; struct module * next_module = module;
while(next_module) { while(next_module) {
estimated_execution_time += admission_info_get_percentile(&next_module->admissions_info); estimated_execution_time += admission_info_get_percentile(&next_module->admissions_info);
next_module = next_module->next_module; //next_module = next_module->next_module;
next_module = next_module->left_module;
} }
/* Adding system start timestamp to avoid negative remaining slack in the following update. They are all cycles */ /* Adding system start timestamp to avoid negative remaining slack in the following update. They are all cycles */
@ -191,7 +192,7 @@ listener_thread_main(void *dummy)
sandbox_request_allocate(module, true, 0, module->name, client_socket, sandbox_request_allocate(module, true, 0, module->name, client_socket,
(const struct sockaddr *)&client_address, (const struct sockaddr *)&client_address,
request_arrival_timestamp, request_arrival_timestamp,remaining_slack, request_arrival_timestamp, request_arrival_timestamp,remaining_slack,
work_admitted, NULL, 0); work_admitted, NULL, NULL, 0);
/* Add to the Global Sandbox Request Scheduler */ /* Add to the Global Sandbox Request Scheduler */
global_request_scheduler_add(sandbox_request); global_request_scheduler_add(sandbox_request);

@ -602,8 +602,6 @@ module_new_from_json(char *file_name)
if (module == NULL) goto module_new_err; if (module == NULL) goto module_new_err;
assert(module); assert(module);
if(is_tail_module) module->is_parent = true;
nodes[i] = module;
// if (tail_module != NULL) { tail_module->next_module = module; } // if (tail_module != NULL) { tail_module->next_module = module; }
// tail_module = module; // tail_module = module;
// tail_module->next_module = NULL; // tail_module->next_module = NULL;
@ -615,6 +613,11 @@ module_new_from_json(char *file_name)
module_set_http_info(module, request_count, request_headers, request_content_type, module_set_http_info(module, request_count, request_headers, request_content_type,
response_count, reponse_headers, response_content_type); response_count, reponse_headers, response_content_type);
module->left_module = NULL;
module->right_module = NULL;
module->parent_module = NULL;
module->is_sandboxcreate = false;
nodes[module_count] = module;
module_count++; module_count++;
} }
@ -623,11 +626,22 @@ module_new_from_json(char *file_name)
} }
if (module_count == 0) panic("%s contained no active modules\n", file_name); if (module_count == 0) panic("%s contained no active modules\n", file_name);
for (int i = 0; i <= module_count; i++) { for (int i = 0; i < module_count; i++)
int left_index = 2 * i + 1; {
int right_index = 2 * i + 2; int left_index = 2 * i + 1;
if (left_index <= module_count) nodes[i]->left_module = nodes[left_index]; int right_index = 2 * i + 2;
if (right_index <= module_count) nodes[i]->right_module = nodes[right_index]; if (left_index < module_count)
{
assert(nodes[left_index]);
nodes[i]->left_module = nodes[left_index];
nodes[left_index]->parent_module = nodes[i];
}
if (right_index < module_count)
{
assert(nodes[right_index]);
nodes[i]->right_module = nodes[right_index];
nodes[right_index]->parent_module = nodes[i];
}
} }
free(nodes); free(nodes);
#ifdef LOG_MODULE_LOADING #ifdef LOG_MODULE_LOADING

@ -1,7 +1,7 @@
include Makefile.inc include Makefile.inc
#TESTS=fibonacci fibonacci2 fibonacci3 big_fibonacci C-Image-Manip empty work work1k work10k work100k work1m forever filesys sockserver sockclient empty #TESTS=fibonacci fibonacci2 fibonacci3 big_fibonacci C-Image-Manip empty work work1k work10k work100k work1m forever filesys sockserver sockclient empty
TESTS=fibonacci big_fibonacci C-Image-Manip empty work work1k work10k work100k work1m forever filesys sockserver sockclient empty TESTS=fibonacci big_fibonacci C-Image-Manip empty work work1k work10k work100k work1m forever filesys sockserver sockclient empty tree
TESTSRT=$(TESTS:%=%_rt) TESTSRT=$(TESTS:%=%_rt)

Binary file not shown.

@ -94,85 +94,85 @@ fib(unsigned long int n)
//return 0; //return 0;
//} //}
main(int argc, char **argv) int main(int argc, char **argv)
{ {
unsigned long n = 0, r; unsigned long n = 0, r;
scanf("%lu", &n); scanf("%lu", &n);
FILE *f = stdout; //FILE *f = stdout;
// unsigned long long st = get_time(), en; // unsigned long long st = get_time(), en;
//r = fib(29); r = fib(n);
// en = get_time(); // en = get_time();
switch(n) { // switch(n) {
case 0: { // case 0: {
char array[4 * 1024] = {0}; // char array[4 * 1024] = {0};
memset(array, 'a', 4 * 1024); // memset(array, 'a', 4 * 1024);
array[4 * 1024 - 1] = 0; // array[4 * 1024 - 1] = 0;
//printf("%s\n", array); // //printf("%s\n", array);
fwrite(array, 1, 4 * 1024 - 1, f); // fwrite(array, 1, 4 * 1024 - 1, f);
break; // break;
} // }
case 1: { // case 1: {
char array[100 * 1024] = {'b'}; // char array[100 * 1024] = {'b'};
memset(array, 'b', 100 * 1024); // memset(array, 'b', 100 * 1024);
array[100 * 1024 - 1] = 0; // array[100 * 1024 - 1] = 0;
//printf("%s\n", array); // //printf("%s\n", array);
fwrite(array, 1, 100 * 1024 - 1, f); // fwrite(array, 1, 100 * 1024 - 1, f);
break; // break;
} // }
case 2: { // case 2: {
char array[200 * 1024] = {'c'}; // char array[200 * 1024] = {'c'};
memset(array, 'c', 200 * 1024); // memset(array, 'c', 200 * 1024);
array[200 * 1024 - 1] = 0; // array[200 * 1024 - 1] = 0;
fwrite(array, 1, 200 * 1024 - 1, f); // fwrite(array, 1, 200 * 1024 - 1, f);
//printf("%s\n", array); // //printf("%s\n", array);
break; // break;
} // }
case 4: { // case 4: {
char array[400 * 1024] = {'d'}; // char array[400 * 1024] = {'d'};
memset(array, 'd', 400 * 1024); // memset(array, 'd', 400 * 1024);
array[400 * 1024 - 1] = 0; // array[400 * 1024 - 1] = 0;
fwrite(array, 1, 400 * 1024 - 1, f); // fwrite(array, 1, 400 * 1024 - 1, f);
//printf("%s\n", array); // //printf("%s\n", array);
break; // break;
} // }
case 6: { // case 6: {
char array[600 * 1024] = {'e'}; // char array[600 * 1024] = {'e'};
memset(array, 'e', 600 * 1024); // memset(array, 'e', 600 * 1024);
array[600 * 1024 - 1] = 0; // array[600 * 1024 - 1] = 0;
fwrite(array, 1, 600 * 1024 - 1, f); // fwrite(array, 1, 600 * 1024 - 1, f);
//printf("%s\n", array); // //printf("%s\n", array);
break; // break;
} // }
case 8: { // case 8: {
char array[800 * 1024] = {'f'}; // char array[800 * 1024] = {'f'};
memset(array, 'f', 800 * 1024); // memset(array, 'f', 800 * 1024);
array[800 * 1024 - 1] = 0; // array[800 * 1024 - 1] = 0;
fwrite(array, 1, 800 * 1024 - 1, f); // fwrite(array, 1, 800 * 1024 - 1, f);
//printf("%s\n", array); // //printf("%s\n", array);
break; // break;
} // }
case 10:{ // case 10:{
char array[1000 * 1024] = {'g'}; // char array[1000 * 1024] = {'g'};
memset(array, 'g', 1000 * 1024); // memset(array, 'g', 1000 * 1024);
array[1000 * 1024 - 1] = 0; // array[1000 * 1024 - 1] = 0;
fwrite(array, 1, 1000 * 1024 - 1, f); // fwrite(array, 1, 1000 * 1024 - 1, f);
//printf("%s\n", array); // //printf("%s\n", array);
break; // break;
} // }
default: printf("error input of n\n"); // default: printf("error input of n\n");
} // }
fclose(f); //fclose(f);
//printf("%lu\n", n); //printf("%lu\n", n);
//printf("%lu\n", r); printf("%lu\n", r);
return 0; return 0;
} }

@ -3,8 +3,8 @@
"name": "fibonacci", "name": "fibonacci",
"path": "fibonacci_wasm.so", "path": "fibonacci_wasm.so",
"port": 10000, "port": 10000,
"expected-execution-us": 600, "expected-execution-us": 5000,
"relative-deadline-us": 2000, "relative-deadline-us": 360000,
"argsize": 1, "argsize": 1,
"http-req-headers": [], "http-req-headers": [],
"http-req-content-type": "text/plain", "http-req-content-type": "text/plain",

@ -0,0 +1,46 @@
{
"active": true,
"name": "cifar10_1",
"path": "cifar10_wasm.so",
"port": 10000,
"relative-deadline-us": 78574,
"argsize": 1,
"http-req-headers": [],
"http-req-content-type": "image/bmp",
"http-req-size": 4096000,
"http-resp-headers": [],
"http-resp-size": 1024,
"http-resp-content-type": "text/plain",
"tail-module": true
},
{
"active": true,
"name": "resize1",
"path": "resize_wasm.so",
"port": 10001,
"relative-deadline-us": 78574,
"argsize": 1,
"http-req-headers": [],
"http-req-content-type": "image/jpeg",
"http-req-size": 1024000,
"http-resp-headers": [],
"http-resp-size": 1024000,
"http-resp-content-type": "image/png"
},
{
"active": true,
"name": "resize2",
"path": "resize_wasm.so",
"port": 10002,
"relative-deadline-us": 78574,
"argsize": 1,
"http-req-headers": [],
"http-req-content-type": "image/jpeg",
"http-req-size": 1024000,
"http-resp-headers": [],
"http-resp-size": 1024000,
"http-resp-content-type": "image/png"
},

@ -0,0 +1,16 @@
{
"active": true,
"name": "tree",
"path": "tree_wasm.so",
"port": 10000,
"expected-execution-us": 5000,
"relative-deadline-us": 360000,
"argsize": 1,
"http-req-headers": [],
"http-req-content-type": "text/plain",
"http-req-size": 1024,
"http-resp-headers": [],
"http-resp-size": 1024,
"http-resp-content-type": "text/plain"
}

@ -0,0 +1,63 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#define MAX_BUF 300
#define MAX_TOKENS 100
// 修改split_string函数使其返回字符串数组
char **split_string(char *str, int *token_count) {
char **p = malloc(MAX_TOKENS * sizeof(char*));
int i = 0;
char *saveptr;
char *token = strtok_r(str, "++", &saveptr);
while (token != NULL) {
p[i++] = token;
token = strtok_r(NULL, "++", &saveptr);
}
*token_count = i; // 设置token计数
return p;
}
int main(int argc, char **argv) {
char *d = malloc(MAX_BUF + 1);
int r = read(0, d, MAX_BUF);
d[r] = '\0';
// 移除输入中的换行符
if (d[r - 1] == '\n') {
d[r - 1] = '\0';
}
int token_count;
char **tokens = split_string(d, &token_count);
// 确保至少有两个token
if (token_count >= 2) {
char *endptr1, *endptr2;
long num1 = strtol(tokens[0], &endptr1, 10);
long num2 = strtol(tokens[1], &endptr2, 10);
// 检查转换是否成功
if (*endptr1 == '\0' && *endptr2 == '\0') {
long sum = num1 + num2;
printf("the sum is %ld\n", sum);
} else {
if (*endptr1 != '\0') {
return -1;
}
if (*endptr2 != '\0') {
return -1;
}
}
} else {
return -1;
}
free(tokens); // 释放分配的内存
free(d);
return 0;
}

Binary file not shown.

@ -0,0 +1,22 @@
Runtime Environment:
CPU Speed: 2400 MHz
Processor Speed: 2400 MHz
RLIMIT_DATA: Infinite
RLIMIT_NOFILE: 1048576 (Increased from 8192)
Core Count: 8
Listener core ID: 1
First Worker core ID: 2
Worker core count: 6
Scheduler Policy: EDF
Sigalrm Policy: BROADCAST
Preemption: Enabled
Quantum: 5000 us
Sandbox Performance Log: Disabled
Starting listener thread
Listener core thread: 7ffff7a006c0
Starting 6 worker thread(s)
C: 01, T: 0x7ffff7bfdd80, F: runtime_start_runtime_worker_threads>
Sandboxing environment ready!
C: 01, T: 0x7ffff7bfdd80, F: module_new>
Stack Size: 524288
Loading…
Cancel
Save