Compare commits

...

14 Commits

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

3
.gitmodules vendored

@ -11,6 +11,9 @@ url = https://github.com/gwsystems/ck.git
[submodule "jsmn"]
path = runtime/thirdparty/jsmn
url = https://github.com/gwsystems/jsmn.git
[submodule "hash"]
path = runtime/thirdparty/hashmap
url = https://github.com/tidwall/hashmap.c.git
[submodule "runtime/tests/gocr"]
path = runtime/tests/gocr
url = https://github.com/gwsystems/gocr.git

@ -9,7 +9,8 @@
"defines": [
"USE_MEM_VM",
"x86_64",
"_GNU_SOURCE"
"_GNU_SOURCE",
"LOG_TO_FILE"
],
"cStandard": "${default}",
"compilerPath": "/usr/bin/clang",

@ -1,7 +1,4 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
@ -47,6 +44,71 @@
"ignoreFailures": true
}
]
},
{
"name": "graph",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/runtime/bin/sledgert",
"args": [
"${workspaceFolder}/runtime/tests/graph.json"
],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"sourceFileMap": {
"/sledge/runtime": "${workspaceFolder}/runtime"
},
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"envFile": "${workspaceFolder}/.env",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
},
{
"name": "utest",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/runtime/utest/map",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"sourceFileMap": {},
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"envFile": "${workspaceFolder}/.env",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
},
{
"name": "C/C++ Runner: Debug Session",
"type": "cppdbg",
"request": "launch",
"args": [],
"stopAtEntry": false,
"externalConsole": false,
"cwd": "/home/weihao/sledge/sledge_tree/runtime/tests/noop",
"program": "/home/weihao/sledge/sledge_tree/runtime/tests/noop/build/Debug/outDebug",
"MIMode": "gdb",
"miDebuggerPath": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
]
}

@ -95,7 +95,24 @@
"compare": "c",
"cstdint": "c",
"format": "c",
"jsmn.h": "c"
"jsmn.h": "c",
"__bit_reference": "c",
"algorithm": "c",
"lock_time.h": "c",
"mcs.h": "c",
"map.h": "c",
"stdio.h": "c",
"hashmap.h": "c",
"mutex": "cpp",
"xmalloc.h": "c",
"stddef.h": "c",
"__mutex_base": "c",
"memory": "c",
"atomic": "c",
"condition_variable": "c",
"ostream": "c",
"stop_token": "c",
"dag_data_split.h": "c"
},
"files.exclude": {
"**/.git": true,
@ -144,6 +161,7 @@
"**/runtime/thirdparty/http-parser/**": true,
"**/runtime/thirdparty/jsmn/**": true,
"**/runtime/thirdparty/dist/**": true,
"**/runtime/thirdparty/hashmap/**": true,
"*.o": true,
"*.bc": true,
"*.wasm": true

@ -0,0 +1 @@
12

@ -0,0 +1,46 @@
Summary:
Total: 5.2029 secs
Slowest: 0.2684 secs
Fastest: 0.0281 secs
Average: 0.2039 secs
Requests/sec: 573.9092
Total data: 158614 bytes
Size/request: 53 bytes
Response time histogram:
0.028 [1] |
0.052 [26] |■
0.076 [15] |■
0.100 [16] |■
0.124 [11] |
0.148 [16] |■
0.172 [46] |■■
0.196 [1042] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
0.220 [968] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
0.244 [702] |■■■■■■■■■■■■■■■■■■■■■■■■■■■
0.268 [143] |■■■■■
Latency distribution:
10% in 0.1811 secs
25% in 0.1894 secs
50% in 0.2028 secs
75% in 0.2231 secs
90% in 0.2385 secs
95% in 0.2441 secs
99% in 0.2531 secs
Details (average, fastest, slowest):
DNS+dialup: 0.0004 secs, 0.0281 secs, 0.2684 secs
DNS-lookup: 0.0000 secs, 0.0000 secs, 0.0000 secs
req write: 0.0002 secs, 0.0000 secs, 0.0249 secs
resp wait: 0.2026 secs, 0.0102 secs, 0.2680 secs
resp read: 0.0001 secs, 0.0000 secs, 0.0012 secs
Status code distribution:
[200] 2986 responses

@ -0,0 +1,247 @@
Summary:
Total: 10.0240 secs
Slowest: 1.1570 secs
Fastest: 0.0692 secs
Average: 0.7488 secs
Requests/sec: 3390.6720
Total data: 33168 bytes
Size/request: 48 bytes
Response time histogram:
0.069 [1] |
0.178 [16] |■■
0.287 [15] |■■
0.396 [10] |■
0.504 [8] |■
0.613 [10] |■
0.722 [391] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
0.831 [43] |■■■■
0.939 [26] |■■■
1.048 [69] |■■■■■■■
1.157 [102] |■■■■■■■■■■
Latency distribution:
10% in 0.6506 secs
25% in 0.6649 secs
50% in 0.6792 secs
75% in 0.9356 secs
90% in 1.0743 secs
95% in 1.0935 secs
99% in 1.1200 secs
Details (average, fastest, slowest):
DNS+dialup: 0.0073 secs, 0.0692 secs, 1.1570 secs
DNS-lookup: 0.0000 secs, 0.0000 secs, 0.0000 secs
req write: 0.0016 secs, 0.0000 secs, 0.0855 secs
resp wait: 0.7388 secs, 0.0480 secs, 1.1547 secs
resp read: 0.0004 secs, 0.0001 secs, 0.0047 secs
Status code distribution:
[200] 691 responses
Error distribution:
[5] Post "http://127.0.0.1:10000": EOF
[33093] Post "http://127.0.0.1:10000": dial tcp 127.0.0.1:10000: connect: connection refused
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:57822->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:57830->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:57838->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:57840->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:57850->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:57856->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:57864->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:57876->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:57882->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:57894->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:57906->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:57918->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:57920->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:57934->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:57938->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:57948->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:57958->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:57964->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:57978->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:57986->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58000->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58008->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58022->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58036->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58052->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58056->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58068->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58082->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58084->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58098->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58104->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58116->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58120->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58134->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58148->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58154->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58170->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58178->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58186->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58190->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58192->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58194->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58198->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58212->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58220->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58230->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58232->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58242->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58246->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58250->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58266->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58270->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58278->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58288->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58300->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58314->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58326->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58332->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58346->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58356->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58366->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58374->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58382->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58392->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58400->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58414->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58416->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58426->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58438->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58450->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58464->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58478->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58492->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58494->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58498->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58508->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58522->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58532->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58546->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58562->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58576->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58588->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58590->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58592->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58594->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58610->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58618->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58634->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58638->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58642->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58648->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58658->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58672->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58688->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58700->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58714->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58730->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58734->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58738->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58744->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58754->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58768->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58780->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58786->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58802->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58816->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58830->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58840->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58848->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58856->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58864->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58876->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58890->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58892->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58908->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58910->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58922->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58928->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58940->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58942->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58948->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58950->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58958->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58966->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58978->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:58994->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59008->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59012->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59016->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59032->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59034->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59044->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59056->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59068->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59078->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59086->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59096->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59108->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59110->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59112->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59120->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59132->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59134->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59140->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59146->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59148->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59152->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59156->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59172->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59180->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59194->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59202->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59218->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59232->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59248->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59264->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59272->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59284->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59300->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59308->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59322->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59332->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59340->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59344->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59352->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59362->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59364->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59376->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59388->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59390->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59392->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59408->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59414->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59420->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59430->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59438->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59454->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59456->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59458->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59462->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59478->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59484->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59486->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59492->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59498->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59512->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59518->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59522->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59536->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59540->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59556->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59562->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59572->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59578->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59592->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59606->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59614->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59618->127.0.0.1:10000: read: connection reset by peer
[1] Post "http://127.0.0.1:10000": read tcp 127.0.0.1:59622->127.0.0.1:10000: read: connection reset by peer

@ -10,10 +10,10 @@ PAGE_SIZE := $(shell getconf PAGESIZE)
# Compiler Settings
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 = -O0 -g -pthread -D_GNU_SOURCE
CC_OPTIONS = -O0 -g -pthread -D_GNU_SOURCE
# CFI Sanitizer
# CC_OPTIONS = -O0 -g -pthread -D_GNU_SOURCE -flto -fvisibility=default -fsanitize=cfi
@ -59,8 +59,8 @@ CFLAGS += -DLOG_TO_FILE
# CFLAGS += -DLOG_PREEMPTION
# CFLAGS += -DLOG_MODULE_LOADING
# CFLAGS += -DOPT_AVOID_GLOBAL_QUEUE
# CFLAGS += -DLOG_RUNTIME_FILE_LOG
CFLAGS += -DLOG_RUNTIME_MEM_LOG
#CFLAGS += -DLOG_RUNTIME_FILE_LOG
CFLAGS += -DLOG_RUNTIME_MEM_LOG
# This dumps per module *.csv files containing the cycle a sandbox has been in RUNNING when each
# page is allocated. This helps understand the relationship to memory allocation and execution time.
@ -150,6 +150,7 @@ fetch:
@git config --global --add safe.directory /sledge/runtime/tests/speechtotext/thirdparty/sphinxbase
@git config --global --add safe.directory /sledge/runtime/thirdparty/http-parser
@git config --global --add safe.directory /sledge/runtime/thirdparty/jsmn
@git config --global --add safe.directory /sledge/runtime/thirdparty/hashmap
@git config --global --add safe.directory /sledge/runtime/tests/C-Image-Manip
@git submodule update --init --recursive

File diff suppressed because one or more lines are too long

@ -0,0 +1,180 @@
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <pthread.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;
char *key;
void *value;
uint32_t key_len;
uint32_t value_len;
uint32_t hash;
bool manage_mvalue;
};
struct map_bucket {
struct map_node *head;
};
struct hashmap {
struct map_bucket buckets[MAP_BUCKET_COUNT];
};
static inline void
map_init(struct hashmap *restrict map)
{
for (int i = 0; i < MAP_BUCKET_COUNT; i++) {
map->buckets[i].head = NULL;
}
}
/* See https://en.wikipedia.org/wiki/Jenkins_hash_function */
static inline uint32_t
jenkins_hash(char *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 void *
map_get(struct hashmap *map, char *key, uint32_t key_len, uint32_t *ret_value_len)
{
void *value = NULL;
uint32_t hash = MAP_HASH(key, key_len);
struct map_bucket *bucket = &map->buckets[hash % MAP_BUCKET_COUNT];
for (struct map_node *node = bucket->head; node != NULL; node = node->next) {
if (node->hash == hash && memcmp(node->key, key, key_len) == 0) {
value = node->value;
*ret_value_len = node->value_len;
goto DONE;
}
}
if (value == NULL) *ret_value_len = 0;
DONE:
return value;
}
/**
* @manage_mvalue manage _ mvalue determines whether the hash table or the caller manages value memory, and true is managed by the hash.
*/
static inline bool
map_set(struct hashmap *map, char *key, uint32_t key_len, void *value, uint32_t value_len, bool manage_mvalue)
{
bool did_set = false;
uint32_t hash = MAP_HASH(key, key_len);
struct map_bucket *bucket = &map->buckets[hash % MAP_BUCKET_COUNT];
for (struct map_node *node = bucket->head; node != NULL; node = node->next) {
if (node->hash == hash && memcmp(node->key, key, key_len) == 0) 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_len = value_len,
.next = bucket->head };
// Copy Key and Value
memcpy(new_node->key, key, key_len);
if (manage_mvalue) {
new_node->value = xmalloc(value_len);
memcpy(new_node->value, value, value_len);
} else {
new_node->value = value;
}
new_node->manage_mvalue = manage_mvalue;
bucket->head = new_node;
did_set = true;
DONE:
return did_set;
}
/**
* @returns boolean if node was deleted or not
*/
static inline bool
map_delete(struct hashmap *map, char *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];
struct map_node *prev = NULL;
struct map_node *node = bucket->head;
while (node != NULL) {
if (node->hash == hash && memcmp(node->key, key, key_len) == 0) {
if (prev == NULL) {
bucket->head = node->next;
} else {
prev->next = node->next;
}
free(node->key);
node->key = NULL;
if (node->manage_mvalue) {
free(node->value);
node->value = NULL;
}
free(node);
node = NULL;
did_delete = true;
break;
}
prev = node;
node = node->next;
}
return did_delete;
}
static inline void
map_upsert(struct hashmap *map, char *key, uint32_t key_len, void *value, uint32_t value_len)
{
uint32_t hash = MAP_HASH(key, key_len);
struct map_bucket *bucket = &map->buckets[hash % MAP_BUCKET_COUNT];
for (struct map_node *node = bucket->head; node != NULL; node = node->next) {
if (node->hash == hash && memcmp(node->key, key, key_len) == 0) {
node->value_len = value_len;
node->value = realloc(node->value, value_len);
assert(node->value);
if (node->manage_mvalue)
{
memcpy(node->value, value, value_len);
}else node->value = value;
return;
}
}
panic("map_upsert: key not found");
}

@ -0,0 +1,246 @@
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <pthread.h>
//#include "lock.h"
#include "xmalloc.h"
typedef pthread_rwlock_t rwlock_t;
#define LOCK_INIT_RW(lock) pthread_rwlock_init(lock, NULL)
#define LOCK_RDLOCK_RW(lock) pthread_rwlock_rdlock(lock)
#define LOCK_WRLOCK_RW(lock) pthread_rwlock_wrlock(lock)
#define LOCK_UNLOCK_RW(lock) pthread_rwlock_unlock(lock)
/* 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;
char *key;
void *value;
uint32_t key_len;
uint32_t value_len;
uint32_t hash;
bool manage_mvalue;
};
struct map_bucket {
rwlock_t lock;
struct map_node *head;
};
struct hashmap {
struct map_bucket buckets[MAP_BUCKET_COUNT];
};
static inline void
map_init(struct hashmap *restrict map)
{
for (int i = 0; i < MAP_BUCKET_COUNT; i++) {
map->buckets[i].head = NULL;
LOCK_INIT_RW(&map->buckets[i].lock);
}
}
/* See https://en.wikipedia.org/wiki/Jenkins_hash_function */
static inline uint32_t
jenkins_hash(char *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 void *
map_get(struct hashmap *map, char *key, uint32_t key_len, uint32_t *ret_value_len)
{
void *value = NULL;
uint32_t hash = MAP_HASH(key, key_len);
struct map_bucket *bucket = &map->buckets[hash % MAP_BUCKET_COUNT];
LOCK_RDLOCK_RW(&bucket->lock);
for (struct map_node *node = bucket->head; node != NULL; node = node->next) {
if (node->hash == hash && memcmp(node->key, key, key_len) == 0) {
value = node->value;
*ret_value_len = node->value_len;
goto DONE;
}
}
if (value == NULL) *ret_value_len = 0;
DONE:
LOCK_UNLOCK_RW(&bucket->lock);
return value;
}
/**
* @manage_mvalue manage _ mvalue determines whether the hash table or the caller manages value memory, and true is managed by the hash.
*/
static inline bool
map_set(struct hashmap *map, char *key, uint32_t key_len, void *value, uint32_t value_len, bool manage_mvalue)
{
bool did_set = false;
uint32_t hash = MAP_HASH(key, key_len);
struct map_bucket *bucket = &map->buckets[hash % MAP_BUCKET_COUNT];
LOCK_WRLOCK_RW(&bucket->lock);
for (struct map_node *node = bucket->head; node != NULL; node = node->next) {
if (node->hash == hash && memcmp(node->key, key, key_len) == 0) 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_len = value_len,
.next = bucket->head };
// Copy Key and Value
memcpy(new_node->key, key, key_len);
if (manage_mvalue) {
new_node->value = xmalloc(value_len);
memcpy(new_node->value, value, value_len);
} else {
new_node->value = value;
}
new_node->manage_mvalue = manage_mvalue;
bucket->head = new_node;
did_set = true;
DONE:
LOCK_UNLOCK_RW(&bucket->lock);
return did_set;
}
/**
* @returns boolean if node was deleted or not
*/
static inline bool
map_delete(struct hashmap *map, char *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_WRLOCK_RW(&bucket->lock);
struct map_node *prev = NULL;
struct map_node *node = bucket->head;
while (node != NULL) {
if (node->hash == hash && memcmp(node->key, key, key_len) == 0) {
if (prev == NULL) {
bucket->head = node->next;
} else {
prev->next = node->next;
}
free(node->key);
node->key = NULL;
if (node->manage_mvalue) {
free(node->value);
node->value = NULL;
}
free(node);
node = NULL;
did_delete = true;
break;
}
prev = node;
node = node->next;
}
LOCK_UNLOCK_RW(&bucket->lock);
return did_delete;
}
static inline void
map_upsert(struct hashmap *map, char *key, uint32_t key_len, void *value, uint32_t value_len)
{
uint32_t hash = MAP_HASH(key, key_len);
struct map_bucket *bucket = &map->buckets[hash % MAP_BUCKET_COUNT];
LOCK_WRLOCK_RW(&bucket->lock);
for (struct map_node *node = bucket->head; node != NULL; node = node->next) {
if (node->hash == hash && memcmp(node->key, key, key_len) == 0) {
node->value_len = value_len;
node->value = realloc(node->value, value_len);
assert(node->value);
if (node->manage_mvalue)
{
memcpy(node->value, value, value_len);
}else node->value = value;
goto DONE;
}
}
panic("map_upsert: key not found");
/*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_RW(&bucket->lock);
}
/*static inline void
map_destroy(struct hashmap *map) {
for (int i = 0; i < MAP_BUCKET_COUNT; i++) {
LOCK_LOCK_RW(&map->buckets[i].lock);
struct map_node *current = map->buckets[i].head;
struct map_node *next;
while (current != NULL) {
next = current->next;
free(current->key);
if (current->manage_mvalue && current->value != NULL) {
free(current->value);
}
free(current);
current = next;
}
LOCK_UNLOCK_RW(&map->buckets[i].lock);
pthread_mutex_destroy(&map->buckets[i].lock);
// 确保头指针设置为 NULL
map->buckets[i].head = NULL;
}
// 如果 hashmap 是动态分配的,这里还需要释放 hashmap 结构本身
// free(map);
}*/

@ -78,7 +78,13 @@ struct module {
/* Entry Function to invoke serverless function */
mod_main_fn_t main;
struct module *next_module; /* the next module in the chain */
struct module **next_module; /* the next module in the DAG */
struct module **pre_module; /* the previous module in the DAG */
char **next_module_names; /* the next modules name in the DAG */
uint32_t next_module_count;
uint32_t pre_module_count;
bool runtime_visited;
uint32_t run_priority;
};
/*************************

@ -12,7 +12,14 @@
#include "module.h"
#include "runtime.h"
#include "sandbox_state.h"
#include "lock.h"
struct sandbox_pre_functions_output {
char * previous_function_output;
ssize_t output_length;
uint32_t run_priority;
struct sandbox_pre_functions_output* next;
};
struct sandbox_request {
uint64_t id;
bool request_from_outside; /* true is yes, false is no */
@ -25,6 +32,8 @@ struct sandbox_request {
uint64_t absolute_deadline; /* cycles */
uint64_t last_update_timestamp; /* cycles */
uint64_t remaining_slack; /* cycles */
struct sandbox_pre_functions_output *pre_functions_output;
pthread_spinlock_t lock;
char * previous_function_output;
ssize_t output_length;
ssize_t previous_request_length;
@ -96,6 +105,9 @@ sandbox_request_allocate(struct module *module, bool request_from_outside, ssize
sandbox_request->last_update_timestamp = enqueue_timestamp;
sandbox_request->remaining_slack = remaining_slack;
/*Avoid pointer suspension*/
sandbox_request->pre_functions_output = NULL;
pthread_spin_init(&sandbox_request->lock, PTHREAD_PROCESS_PRIVATE);
/*
* Admissions Control State
* Assumption: an estimate of 0 should have been interpreted as a rejection
@ -107,3 +119,114 @@ sandbox_request_allocate(struct module *module, bool request_from_outside, ssize
return sandbox_request;
}
/**
* Allocate a new node for the list of previous function outputs. Ensures that
* the list remains sorted based on run_priority, which must be less than 6.
* @param head the head of struct sandbox_request->previous_function_output
* @param output the output of the previous function
* @param output_length the length of the output
* @param run_priority the run_priority of the sandbox->module->run_priority
* The first four bytes of the data represent the length of the data, and the tail character & serves as the delimiter marker
**/
static inline void
pre_functions_output_request_add(struct sandbox_request *request, char *output, ssize_t output_length, uint32_t run_priority)
{
assert(run_priority < 6);
// pthread_spin_lock(&request->lock);
if (!output || output_length <= 0) {
debuglog("output is null or output_length is <= 0");
// goto done;
return;
}
struct sandbox_pre_functions_output **head = &request->pre_functions_output;
struct sandbox_pre_functions_output *new_node = (struct sandbox_pre_functions_output *)malloc(sizeof(struct sandbox_pre_functions_output));
if (!new_node) {
panic("Could not allocate memory for new node");
}
new_node->previous_function_output = (char *)malloc(output_length);
if (!new_node->previous_function_output) {
free(new_node);
panic("Could not allocate memory for output buffer");
}
//memcpy(new_node->previous_function_output, output, output_length);
new_node->previous_function_output = output;
new_node->output_length = output_length;
new_node->run_priority = run_priority;
new_node->next = NULL;
if (*head == NULL || (*head)->run_priority >= run_priority) {
new_node->next = *head;
*head = new_node;
} else {
struct sandbox_pre_functions_output *current = *head;
while (current->next && current->next->run_priority < run_priority) {
current = current->next;
}
new_node->next = current->next;
current->next = new_node;
}
//done:
// pthread_spin_unlock(&request->lock);
}
/**
* The output result of the sandbox in the splicing structure
**/
static inline void
concatenate_outputs(struct sandbox_request *request) {
size_t total_length = 0; // Calculate total length without extra for null character
struct sandbox_pre_functions_output *current = request->pre_functions_output;
if(current && !current->next)
{
char *previous_function_output = (char *)malloc(current->output_length);
if (!previous_function_output) {
panic("Could not allocate memory for concatenated output");
return;
}
memcpy(previous_function_output, current->previous_function_output, current->output_length);
request->output_length = current->output_length;
request->previous_function_output = previous_function_output;
return;
}
/* 4 bytes of data represents the length of the data */
while (current != NULL) {
total_length += current->output_length + 4;
current = current->next;
}
char *concatenated_output = (char *)malloc(total_length);
if (!concatenated_output) {
panic("Could not allocate memory for concatenated output");
return;
}
char *copy_dest = concatenated_output;
current = request->pre_functions_output;
while (current != NULL) {
size_t copy_length = current->output_length;
*(uint32_t *)copy_dest = (uint32_t)copy_length;
copy_dest += 4;
memcpy(copy_dest, current->previous_function_output, copy_length);
copy_dest += copy_length;
current = current->next;
}
if (request->previous_function_output != NULL) {
free(request->previous_function_output);
request->previous_function_output = NULL;
}
request->output_length = total_length;
request->previous_function_output = concatenated_output;
}

@ -35,6 +35,7 @@ sandbox_set_as_initialized(struct sandbox *sandbox, struct sandbox_request *sand
sandbox->state = SANDBOX_SET_AS_INITIALIZED;
sandbox->request_from_outside = sandbox_request->request_from_outside;
concatenate_outputs(sandbox_request);
sandbox->previous_function_output = sandbox_request->previous_function_output;
sandbox->output_length = sandbox_request->output_length;
sandbox->previous_request_length = sandbox_request->previous_request_length;

@ -69,6 +69,7 @@ err_allocate:
client_socket_send(request->socket_descriptor, 503);
client_socket_close(request->socket_descriptor, &request->socket_address);
free(request);
request = NULL;
goto done;
}
@ -108,6 +109,7 @@ err_allocate:
client_socket_send(request->socket_descriptor, 503);
client_socket_close(request->socket_descriptor, &request->socket_address);
free(request);
request = NULL;
goto done;
}
static inline struct sandbox *
@ -138,6 +140,7 @@ err_allocate:
client_socket_send(sandbox_request->socket_descriptor, 503);
client_socket_close(sandbox_request->socket_descriptor, &sandbox->client_address);
free(sandbox_request);
sandbox_request = NULL;
err:
sandbox = NULL;
goto done;

@ -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;
}

@ -8,9 +8,12 @@
#include "scheduler.h"
#include "module.h"
#include "software_interrupt.h"
#include "map.h"
extern uint64_t system_start_timestamp;
lock_t lock;
#define OUTPUT_BUFER_SIZE 1024*5
__thread struct sandbox *worker_thread_current_sandbox = NULL;
__thread struct sandbox_context_cache local_sandbox_context_cache = {
@ -70,7 +73,27 @@ current_sandbox_start(void)
char *error_message = "";
sandbox_initialize_stdio(sandbox);
struct module * next_module = sandbox->module->next_module;
int next_module_idx = sandbox->module->next_module_count;
static struct hashmap *sandbox_req_map = NULL;
static struct hashmap *sandbox_request_id = NULL;
if (sandbox_req_map == NULL || sandbox_request_id == NULL) {
if(sandbox_req_map == NULL)
{
sandbox_req_map = malloc(sizeof(struct hashmap));
map_init(sandbox_req_map);
}
if(sandbox_request_id == NULL)
{
sandbox_request_id = malloc(sizeof(struct hashmap));
map_init(sandbox_request_id);
}
assert(sandbox_req_map != NULL);
assert(sandbox_request_id != NULL);
}
struct module **next_module = sandbox->module->next_module;
/*
* Add the client fd to epoll if it is the first or last sandbox in the chain because they
@ -118,6 +141,12 @@ current_sandbox_start(void)
*/
goto err;
} else if (next_module != NULL) {
assert(next_module_idx);
assert(next_module);
size_t next_module_pre_count = next_module[0]->pre_module_count;
assert(next_module_pre_count);
if (next_module_idx > 1 || (next_module_idx == 1 && next_module_pre_count == 1))
{
/* 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;
char * pre_func_output = (char *)malloc(output_length);
@ -127,20 +156,32 @@ current_sandbox_start(void)
};
memcpy(pre_func_output, sandbox->request_response_data + sandbox->request_length, output_length);
uint64_t enqueue_timestamp = __getcycles();
//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,
// sandbox->id, sandbox->module->name, sandbox->remaining_slack);
for (size_t i = 0; i < next_module_idx; i++)
{
struct module * next_module_node = next_module[i];
assert(next_module_node);
char * individual_pre_func_output = (char *)malloc(output_length);
if (!individual_pre_func_output) {
fprintf(stderr, "Failed to allocate memory for the individual previous output: %s\n", strerror(errno));
free(pre_func_output);
goto err;
}
memcpy(individual_pre_func_output, pre_func_output, output_length);
uint64_t enqueue_timestamp = __getcycles();
struct sandbox_request *sandbox_request =
sandbox_request_allocate(next_module, false, sandbox->request_length,
next_module->name, sandbox->client_socket_descriptor,
sandbox_request_allocate(next_module_node, false, sandbox->request_length,
next_module_node->name, sandbox->client_socket_descriptor,
(const struct sockaddr *)&sandbox->client_address,
sandbox->request_arrival_timestamp, enqueue_timestamp,
sandbox->remaining_slack, true, pre_func_output, output_length);
sandbox->remaining_slack, true, NULL, 0);
/* TODO: All sandboxs in the chain share the same request id, but sandbox_request_allocate()
* will busy-wait to generate an unique id, should we optimize it here?
*/
sandbox_request->id = sandbox->id;
pre_functions_output_request_add(sandbox_request, individual_pre_func_output, output_length, sandbox->module->run_priority);
#ifdef OPT_AVOID_GLOBAL_QUEUE
/* 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) {
@ -160,12 +201,108 @@ current_sandbox_start(void)
#else
/* Add to the Global Sandbox Request Scheduler */
global_request_scheduler_add(sandbox_request);
}
#endif
/* Remove the client fd from epoll if it is the first sandbox in the chain */
if (sandbox->request_from_outside) {
sandbox_remove_from_epoll(sandbox);
}
/*free memory of pre_func_out, Because it has been deeply copied its copy into requestbecause */
free(pre_func_output);
pre_func_output = NULL;
sandbox_set_as_returned(sandbox, SANDBOX_RUNNING);
}else if (next_module_idx == 1 && next_module_pre_count > 1)
{
static bool lock_flag = true;
if (lock_flag)
{
LOCK_INIT(&lock);
lock_flag = false;
}
/*Before each id is put into the hash table, the key needs to add a "module handle"*/
struct module * next_module_node = next_module[0];
assert(next_module_node);
char *cur_request_id = NULL;
int key_len = snprintf(NULL, 0, "%s%lu", next_module_node->name, sandbox->id) + 1;
cur_request_id = (char *)malloc(key_len);
assert(cur_request_id);
snprintf(cur_request_id, key_len, "%s%lu", next_module_node->name, sandbox->id);
uint32_t ret_value_len;
uint32_t rest_pre_count = 888;
/*calculation the pre_function_out*/
ssize_t output_length = sandbox->request_response_data_length - sandbox->request_length;
char * 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));
goto err;
};
memcpy(pre_func_output, sandbox->request_response_data + sandbox->request_length, output_length);
//debuglog("the ID %lu %s pre_func_output is %s\n", sandbox->id, sandbox->module->name, pre_func_output);
LOCK_LOCK(&lock);
uint64_t *request_id = (uint64_t *)map_get(sandbox_request_id, cur_request_id, strlen(cur_request_id), &ret_value_len);
bool mapflag = false;
if (!request_id) {
uint64_t enqueue_timestamp = __getcycles();
//mem_log("time %lu request id:%d executing, name:%s remaining slack %lu\n", current_rs,
// sandbox->id, sandbox->module->name, sandbox->remaining_slack);
struct sandbox_request *sandbox_request =
sandbox_request_allocate(next_module_node, false, sandbox->request_length,
next_module_node->name, sandbox->client_socket_descriptor,
(const struct sockaddr *)&sandbox->client_address,
sandbox->request_arrival_timestamp, enqueue_timestamp,
sandbox->remaining_slack, true, NULL, 0);
/* TODO: All sandboxs in the chain share the same request id, but sandbox_request_allocate()
* will busy-wait to generate an unique id, should we optimize it here?
*/
sandbox_request->id = sandbox->id;
uint32_t module_pre_count = next_module_pre_count;
module_pre_count--;
assert(module_pre_count);
if(!map_set(sandbox_request_id, cur_request_id, strlen(cur_request_id), &module_pre_count, sizeof(uint32_t), true)) panic("the map of sandbox_request_id is NULL\n");
if(!map_set(sandbox_req_map, cur_request_id, strlen(cur_request_id), sandbox_request, sizeof(struct sandbox_request *), false)) panic("the map of sandbox_request is NULL\n");
mapflag = true;
}
LOCK_UNLOCK(&lock);
struct sandbox_request *sandbox_request = map_get(sandbox_req_map, cur_request_id, strlen(cur_request_id), &ret_value_len);
if(!sandbox_request) panic("the map of sandbox_request is NULL\n");
if (mapflag)
{
pre_functions_output_request_add(sandbox_request, pre_func_output, output_length, sandbox->module->run_priority);
}else{
pthread_spin_lock(&sandbox_request->lock);
pre_functions_output_request_add(sandbox_request, pre_func_output, output_length, sandbox->module->run_priority);
if (!request_id) {
panic("Request ID not found or invalid\n");
}else {
rest_pre_count = *request_id;
}
if(rest_pre_count == 888) panic("the rest_pre_count is not get requst_id\n");
rest_pre_count--;
if (rest_pre_count != 0)
{
map_upsert(sandbox_request_id, cur_request_id, strlen(cur_request_id), &rest_pre_count, sizeof(uint32_t));
}else{
uint64_t enqueue_timestamp = __getcycles();
sandbox_request->enqueue_timestamp = enqueue_timestamp;
global_request_scheduler_add(sandbox_request);
map_delete(sandbox_req_map, cur_request_id, strlen(cur_request_id));
map_delete(sandbox_request_id, cur_request_id, strlen(cur_request_id));
}
pthread_spin_unlock(&sandbox_request->lock);
}
free(cur_request_id);
cur_request_id = NULL;
if (sandbox->request_from_outside) {
sandbox_remove_from_epoll(sandbox);
}
sandbox_set_as_returned(sandbox, SANDBOX_RUNNING);
goto done;
}else
{
error_message = "the strcuture of DAG is not supported\n";
goto err;
}
} else {
/* Retrieve the result, construct the HTTP response, and send to client */
if (sandbox_send_response(sandbox) < 0) {

@ -9,6 +9,8 @@
#include "runtime.h"
extern uint64_t system_start_timestamp;
/*When reading the json file, the size has been determined at module.c JSON_MAX_ELEMENT_COUNT*/
const int QUEUE_SIZE = 16;
/*
* Descriptor of the epoll instance used to monitor the socket descriptors of registered
* serverless modules. The listener cores listens for incoming client requests through this.
@ -176,13 +178,31 @@ listener_thread_main(void *dummy)
continue;
}
/* get total estimated execution time */
uint64_t estimated_execution_time = admission_info_get_percentile(&module->admissions_info);
struct module * next_module = module;
while(next_module) {
estimated_execution_time += admission_info_get_percentile(&next_module->admissions_info);
next_module = next_module->next_module;
uint64_t estimated_execution_time = 0;
int front = 0, rear = 0;
struct module **queue = malloc(QUEUE_SIZE * sizeof(struct module*));
if (queue == NULL) {
panic("Failed to allocate listen.c queue memory for queue");
}
queue[rear++] = module;
while (rear != front)
{
struct module *current_module = queue[front++];
estimated_execution_time += admission_info_get_percentile(&current_module->admissions_info);
for (int i = 0; i < current_module->next_module_count; i++) {
if (current_module->next_module[i] != NULL && !current_module->next_module[i]->runtime_visited)
{
queue[rear++] = current_module->next_module[i];
current_module->next_module[i]->runtime_visited = true;
}
}
/*Recover the flags of the module here, so that it can be accessed next time.*/
current_module->runtime_visited = false;
assert(rear <= QUEUE_SIZE);
assert(front <= QUEUE_SIZE);
}
free(queue);
/* Adding system start timestamp to avoid negative remaining slack in the following update. They are all cycles */
uint64_t remaining_slack = system_start_timestamp + module->relative_deadline - estimated_execution_time;

@ -228,6 +228,7 @@ runtime_configure()
if (runtime_sandbox_perf_log == NULL) { perror("sandbox perf log"); }
fprintf(runtime_sandbox_perf_log, "threadid,id,function,state,deadline,actual,queued,initializing,runnable,"
"running,blocked,returned,memory\n");
//fflush(runtime_sandbox_perf_log);
} else {
printf("\tSandbox Performance Log: Disabled\n");
}

@ -93,6 +93,7 @@ mem_log(char const * fmt, ...)
} else {
/* Write Success */
log_obj.offset += n;
// dump_log_to_file(log_obj);
}
}

@ -19,6 +19,7 @@
const int JSON_MAX_ELEMENT_COUNT = 16;
const int JSON_MAX_ELEMENT_SIZE = 1024;
const int PRE_MODULE_COUNT = 4;
/*************************
* Private Static Inline *
@ -374,7 +375,10 @@ module_new_from_json(char *file_name)
int module_count = 0;
char *request_headers = NULL;
char *reponse_headers = NULL;
struct module *tail_module = NULL;
struct module **nodes = malloc(JSON_MAX_ELEMENT_COUNT * sizeof(struct module*));
if (nodes == NULL) {
panic("Memory allocation failed for nodes array\n");
}
for (int i = 0; i < total_tokens; i++) {
assert(tokens[i].type == JSMN_OBJECT);
@ -397,9 +401,12 @@ module_new_from_json(char *file_name)
}
memset(reponse_headers, 0, HTTP_MAX_HEADER_LENGTH * HTTP_MAX_HEADER_COUNT);
uint32_t next_module_count = 0;
uint32_t pre_module_count = 0;
int32_t request_size = 0;
int32_t response_size = 0;
int32_t argument_count = 0;
uint32_t priority = 1;
uint32_t port = 0;
uint32_t relative_deadline_us = 0;
uint32_t expected_execution_us = 0;
@ -412,6 +419,7 @@ module_new_from_json(char *file_name)
int ntoks = 2 * tokens[i].size;
char request_content_type[HTTP_MAX_HEADER_VALUE_LENGTH] = { 0 };
char response_content_type[HTTP_MAX_HEADER_VALUE_LENGTH] = { 0 };
char **next_module_names = NULL;
for (; j < ntoks;) {
int ntks = 1;
@ -440,11 +448,38 @@ module_new_from_json(char *file_name)
if (buffer < 0 || buffer > 65535)
panic("Expected port between 0 and 65535, saw %d\n", buffer);
port = buffer;
}else if (strcmp(key, "priority") == 0)
{
priority = atoi(val);
if (priority < 0 || priority > 5)
panic("Expected priority between 0 and 5, saw %d\n", priority);
} else if (strcmp(key, "argsize") == 0) {
// Validate in expected range 0..127. Unclear if 127 is an actual hard limit
argument_count = atoi(val);
if (argument_count < 0 || argument_count > 127)
panic("Expected argument count between 0 and 127, saw %d\n", argument_count);
} else if (strcmp(key, "pre_module_count") == 0)
{
pre_module_count = atoi(val);
if (pre_module_count < 0)
panic("Expected pre_module_count to be nonnegative, saw %d\n", pre_module_count);
} else if (strcmp(key, "next_modules") == 0)
{
assert(tokens[i + j + 1].type == JSMN_ARRAY);
request_count = tokens[i + j + 1].size;
ntks += request_count;
ntoks += request_count;
next_module_names = malloc(request_count * sizeof(char *));
next_module_count = request_count;
int array_index = 0;
for (int k = 1; k <= request_count; k++) {
jsmntok_t *g = &tokens[i + j + k + 1];
int name_length = g->end - g->start;
next_module_names[array_index] = malloc(name_length + 1);
strncpy(next_module_names[array_index], file_buffer + g->start, name_length);
next_module_names[array_index][name_length] = '\0';
array_index++;
}
} else if (strcmp(key, "active") == 0) {
assert(tokens[i + j + 1].type == JSMN_PRIMITIVE);
if (val[0] == 't') {
@ -566,28 +601,88 @@ module_new_from_json(char *file_name)
relative_deadline_us, port, request_size, response_size,
admissions_percentile, expected_execution_us);
if (module == NULL) goto module_new_err;
if(next_module_count == 0)
{
module->next_module_names = NULL;
}else
{
module->next_module_names = malloc(next_module_count * sizeof(char*));
if (module->next_module_names == NULL) panic("Failed to allocate memory for next_module_names");
for (int i = 0; i < next_module_count; i++) {
module->next_module_names[i] = strdup(next_module_names[i]);
if (module->next_module_names[i] == NULL) {
panic("Memory allocation failed for next_module_names[%d].\n", i);
}
}
}
module->next_module_count = next_module_count;
module->pre_module_count = pre_module_count;
module->next_module = NULL;
module->pre_module = NULL;
module->runtime_visited = false;
module->run_priority = priority;
assert(module);
if (tail_module != NULL) { tail_module->next_module = module; }
tail_module = module;
tail_module->next_module = NULL;
/* if this is the tail module, reset tail_module to NULL to build another new chain */
if (is_tail_module) {
tail_module = NULL;
}
module_set_http_info(module, request_count, request_headers, request_content_type,
response_count, reponse_headers, response_content_type);
nodes[module_count] = module;
module_count++;
}
free(request_headers);
free(reponse_headers);
for (int i = 0; i < next_module_count; i++) {
free(next_module_names[i]);
}
free(next_module_names);
}
if (module_count == 0) panic("%s contained no active modules\n", file_name);
for (int i = 0; i < module_count; i++) {
assert(nodes[i]);
uint32_t next_module_count = nodes[i]->next_module_count;
if (next_module_count == 0) continue;
nodes[i]->next_module = (struct module**) malloc( next_module_count * sizeof(struct module*));
if (nodes[i]->next_module == NULL) panic("Failed to allocate memory for next_module");
for (int next_module_mem = 0; next_module_mem < next_module_count; next_module_mem++) nodes[i]->next_module[next_module_mem] = NULL;
for (int j = 0; j < next_module_count; j++) {
for (int m = i + 1; m < module_count; m++) {
if (strncmp(nodes[i]->next_module_names[j], nodes[m]->name, MODULE_MAX_NAME_LENGTH) == 0) {
assert(nodes[m]);
uint32_t precount = nodes[m]->pre_module_count;
assert(precount);
if (nodes[m]->pre_module == NULL) {
nodes[m]->pre_module = (struct module**) malloc(precount * sizeof(struct module*));
if (nodes[m]->pre_module == NULL) panic("Failed to allocate memory for pre_module");
for (int k = 0; k < precount; k++) {
nodes[m]->pre_module[k] = NULL;
}
}
nodes[i]->next_module[j] = nodes[m];
int preflag = 0;
for (; preflag < precount; preflag++) {
if(nodes[m]->pre_module[preflag] == NULL) break;
}
nodes[m]->pre_module[preflag] = nodes[i];
break;
}
}
}
}
/*Avoid module memory copy overhead*/
for(int i = 0; i < module_count; i++) {
for (int j = 0; j < nodes[i]->next_module_count; j++)
{
free(nodes[i]->next_module_names[j]);
}
nodes[i]->next_module_names = NULL;
}
free(nodes);
nodes = NULL;
#ifdef LOG_MODULE_LOADING
debuglog("Loaded %d module%s!\n", module_count, module_count > 1 ? "s" : "");
#endif

@ -41,7 +41,7 @@ uint64_t runtime_worker_threads_remaining_slack[RUNTIME_WORKER_THREAD_CORE_COUNT
void
runtime_cleanup()
{
if (runtime_sandbox_perf_log != NULL) fflush(runtime_sandbox_perf_log);
//if (runtime_sandbox_perf_log != NULL) fflush(runtime_sandbox_perf_log);
software_interrupt_deferred_sigalrm_max_print();
exit(EXIT_SUCCESS);

@ -152,6 +152,16 @@ sandbox_allocate(struct sandbox_request *sandbox_request)
/* Set state to initializing */
sandbox_set_as_initialized(sandbox, sandbox_request, now);
struct sandbox_pre_functions_output *current = sandbox_request->pre_functions_output;
struct sandbox_pre_functions_output *next = NULL;
while (current) {
next = current->next;
free(current->previous_function_output);
free(current);
current = next;
}
sandbox_request->pre_functions_output = NULL;
pthread_spin_destroy(&sandbox_request->lock);
free(sandbox_request);
done:
return sandbox;
@ -186,6 +196,7 @@ sandbox_free(struct sandbox *sandbox)
assert(sandbox->state == SANDBOX_ERROR || sandbox->state == SANDBOX_COMPLETE);
int rc;
//printf("ID %lu of sandbox %s removing sandbox from queue\n",sandbox->id, sandbox->module->name);
if (sandbox->previous_function_output != NULL) {
free(sandbox->previous_function_output);
sandbox->previous_function_output = NULL;

@ -2,16 +2,17 @@ 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 big_fibonacci C-Image-Manip empty work work1k work10k work100k work1m forever filesys sockserver sockclient empty
TESTS2=fibonacciadd mem
TESTSRT=$(TESTS:%=%_rt)
.PHONY: all clean rttests tinyekf cifar10 gocr sod
TESTSRT2=$(TESTS2:%=%_rt)
.PHONY: all clean rttests tinyekf cifar10 gocr sod add
all: rttests tinyekf cifar10 gocr sod
@echo "Test Compilation done!"
rttests: $(TESTSRT)
add: $(TESTSRT2)
clean:
@echo "Cleaning Test Applications"

File diff suppressed because one or more lines are too long

@ -0,0 +1 @@
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

@ -0,0 +1,15 @@
#!/bin/bash
function usage {
echo "$0 [cpu-log]"
exit 1
}
path="/home/hai/sledge-old/runtime/tests"
#test work1k 2000
server_log_file="edf_1k.log"
$path/compare/start_compare.sh $server_log_file >/dev/null 2>&1 &
echo "sledge is running"
./hey_test_compare.sh 60 22
$path/kill_sledge.sh

File diff suppressed because one or more lines are too long

@ -0,0 +1,24 @@
function usage {
echo "$0 [duration(s)] [concurrency]"
exit 1
}
if [ $# != 2 ] ; then
usage
exit 1;
fi
duration=$1
concurrency=$2
f1="1byte_"$concurrency".txt"
echo $f1
f2="0.4k_"$concurrency".txt"
./test_8c.sh $f1 $duration $concurrency 1byte_file 10000 2>&1 &
pid1=$!
./test_8c.sh $f2 $duration $concurrency 410byte_file 10004 2>&1 &
pid4=$!
wait -f $pid1
wait -f $pid2
printf "[OK]\n"

@ -0,0 +1,29 @@
#!/bin/bash
function usage {
echo "$0 [perf output file, chain_function_perf.log or single_function_perf.log or opt_function_perf.log]"
exit 1
}
if [ $# != 1 ] ; then
usage
exit 1;
fi
output=$1
declare project_path="$(
cd "$(dirname "$0")/../../.."
pwd
)"
echo $project_path
path=`pwd`
#export SLEDGE_DISABLE_PREEMPTION=true
export SLEDGE_CPU_SPEED=2400
export SLEDGE_SCHEDULER=EDF
export SLEDGE_SIGALRM_HANDLER=BROADCAST
export SLEDGE_SANDBOX_PERF_LOG=$path/$output
echo $SLEDGE_SANDBOX_PERF_LOG
cd $project_path/runtime/bin
LD_LIBRARY_PATH="$(pwd):$LD_LIBRARY_PATH" ./sledgert ../tests/compare/test_work1k.json

@ -0,0 +1,22 @@
function usage {
echo "$0 [output file] [duration(s)] [concurrency] [image file] [port]"
exit 1
}
if [ $# != 5 ] ; then
echo "input parameters are not 5"
usage
exit 1;
fi
output=$1
duration=$2
concurrency=$3
image=$4
port=$5
echo "hey -disable-compression -disable-keepalive -disable-redirects -c $concurrency -z $duration\s -t 0 -m GET -D "$image" "http://127.0.0.1:$port" > $output"
#hey -disable-compression -disable-keepalive -disable-redirects -c 1 -q $rps -z $duration\s -cpus 1 -t 0 -m GET -D "$image" "http://10.10.1.1:$port"
#hey -disable-compression -disable-keepalive -disable-redirects -c $concurrency -z 20s -t 0 -m GET -D "$image" "http://10.10.1.1:$port"
hey -disable-compression -disable-keepalive -disable-redirects -n 5000 -c $concurrency -z $duration\s -t 0 -m GET -D "$image" "http://127.0.0.1:$port" > $output

@ -0,0 +1,136 @@
{
"active": true,
"name": "work1k1_1",
"path": "work1k_wasm.so",
"port": 10000,
"relative-deadline-us": 50000,
"argsize": 1,
"priority": 1,
"pre_module_count": 0,
"next_modules": ["work1k1_2", "work1k1_3"],
"http-req-headers": [],
"http-req-content-type": "text/plain",
"http-req-size": 1200,
"http-resp-headers": [],
"http-resp-size": 1200,
"http-resp-content-type": "text/plain"
},
{
"active": true,
"name": "work1k1_2",
"path": "work1k_wasm.so",
"port": 10001,
"relative-deadline-us": 50000,
"argsize": 1,
"priority": 1,
"pre_module_count": 1,
"next_modules": ["work1k1_4"],
"http-req-headers": [],
"http-req-content-type": "text/plain",
"http-req-size": 1200,
"http-resp-headers": [],
"http-resp-size": 1200,
"http-resp-content-type": "text/plain"
},
{
"active": true,
"name": "work1k1_3",
"path": "work1k_wasm.so",
"port": 10002,
"relative-deadline-us": 50000,
"argsize": 1,
"priority": 2,
"pre_module_count": 1,
"next_modules": ["work1k1_4"],
"http-req-headers": [],
"http-req-content-type": "text/plain",
"http-req-size": 1200,
"http-resp-headers": [],
"http-resp-size": 1200,
"http-resp-content-type": "text/plain"
},
{
"active": true,
"name": "work1k1_4",
"path": "work1k_wasm.so",
"port": 10003,
"relative-deadline-us": 50000,
"argsize": 1,
"priority": 1,
"pre_module_count": 2,
"next_modules": [],
"http-req-headers": [],
"http-req-content-type": "text/plain",
"http-req-size": 1200,
"http-resp-headers": [],
"http-resp-size": 1200,
"http-resp-content-type": "text/plain",
},
{
"active": true,
"name": "work1k2_1",
"path": "work1k_wasm.so",
"port": 10004,
"relative-deadline-us": 90000,
"argsize": 1,
"priority": 1,
"pre_module_count": 0,
"next_modules": ["work1k2_2", "work1k2_3"],
"http-req-headers": [],
"http-req-content-type": "text/plain",
"http-req-size": 1200,
"http-resp-headers": [],
"http-resp-size": 1200,
"http-resp-content-type": "text/plain"
},
{
"active": true,
"name": "work1k2_2",
"path": "work1k_wasm.so",
"port": 10005,
"relative-deadline-us": 90000,
"argsize": 1,
"priority": 1,
"pre_module_count": 1,
"next_modules": ["work1k2_4"],
"http-req-headers": [],
"http-req-content-type": "text/plain",
"http-req-size": 1200,
"http-resp-headers": [],
"http-resp-size": 1200,
"http-resp-content-type": "text/plain"
},
{
"active": true,
"name": "work1k2_3",
"path": "work1k_wasm.so",
"port": 10006,
"relative-deadline-us": 90000,
"argsize": 1,
"priority": 2,
"pre_module_count": 1,
"next_modules": ["work1k2_4"],
"http-req-headers": [],
"http-req-content-type": "text/plain",
"http-req-size": 1200,
"http-resp-headers": [],
"http-resp-size": 1200,
"http-resp-content-type": "text/plain"
},
{
"active": true,
"name": "work1k2_4",
"path": "work1k_wasm.so",
"port": 10007,
"relative-deadline-us": 90000,
"argsize": 1,
"priority": 1,
"pre_module_count": 2,
"next_modules": [],
"http-req-headers": [],
"http-req-content-type": "text/plain",
"http-req-size": 1200,
"http-resp-headers": [],
"http-resp-size": 1200,
"http-resp-content-type": "text/plaini",
},

@ -0,0 +1,99 @@
#include "dag_data_split.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct DataNode {
uint32_t dataLength;
char *data;
struct DataNode *next;
};
DataNode* splitData(char *buffer, uint32_t bufferSize) {
DataNode *head = NULL;
DataNode *tail = NULL;
uint32_t offset = 0;
while (offset < bufferSize) {
if (offset + 4 > bufferSize) {
break;
}
uint32_t dataLength = *(uint32_t *)(buffer + offset);
offset += 4;
if (offset + dataLength > bufferSize) {
break;
}
DataNode *newNode = (DataNode *)malloc(sizeof(DataNode));
if (newNode == NULL) {
perror("Memory allocation failed");
freeDataNodes(head); // 释放已分配的节点内存
return NULL;
}
newNode->data = (char *)malloc(dataLength);
if (newNode->data == NULL) {
free(newNode);
perror("Memory allocation failed");
freeDataNodes(head); // 释放已分配的节点内存
return NULL;
}
memcpy(newNode->data, buffer + offset, dataLength);
newNode->dataLength = dataLength;
newNode->next = NULL;
if (head == NULL) {
head = newNode;
} else {
tail->next = newNode;
}
tail = newNode;
offset += dataLength;
}
return head;
}
void freeDataNodes(DataNode *head) {
while (head != NULL) {
DataNode *next = head->next;
free(head->data);
free(head);
head = next;
}
}
void printDataList(DataNode *head) {
int index = 0;
DataNode *current = head;
while (current != NULL) {
printf("Data %d: Length = %u\n", index, current->dataLength);
index++;
current = current->next;
}
}
int getDataNodeCount(DataNode *head) {
int count = 0;
DataNode *current = head;
while (current != NULL) {
count++;
current = current->next;
}
return count;
}
const char* getDataNodeByIndex(DataNode *head, int index) {
int count = 1;
DataNode *current = head;
while (current != NULL) {
if (count == index) {
return current->data;
}
count++;
current = current->next;
}
return NULL; // 如果索引超出范围返回NULL
}

@ -0,0 +1,17 @@
#pragma once
#include <stdint.h>
typedef struct DataNode DataNode;
DataNode* splitData(char *buffer, uint32_t bufferSize);
void freeDataNodes(DataNode *head);
void printDataList(DataNode *head);
int getDataNodeCount(DataNode *head);
/**
* @param index is form 1 to n
*/
const char* getDataNodeByIndex(DataNode *head, int index);

@ -0,0 +1,60 @@
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include "dag_data_split.h" // 包含数据处理的API
unsigned long int fib(unsigned long int n) {
if (n <= 1) return n;
return fib(n - 1) + fib(n - 2);
}
int main() {
char buffer[1024]; // Buffer to store input data
ssize_t bytes_read = read(0, buffer, sizeof(buffer));
if (bytes_read < 0) {
perror("Error reading input");
return 1;
}
DataNode *dataList = splitData(buffer, bytes_read);
if (dataList == NULL) {
fprintf(stderr, "Failed to split data.\n");
return 1;
}
// 读取解析出的第一个和第二个数字
unsigned long int num1, num2;
const char *firstdata = getDataNodeByIndex(dataList, 1);
const char *seconddata = getDataNodeByIndex(dataList, 2);
if (firstdata == NULL || seconddata == NULL) {
fprintf(stderr, "Not enough data for two numbers.\n");
freeDataNodes(dataList);
return 1;
}
if (sscanf(firstdata, "%lu", &num1) != 1 || sscanf(seconddata, "%lu", &num2) != 1) {
fprintf(stderr, "Failed to parse the numbers correctly.\n");
freeDataNodes(dataList);
return 1;
}
unsigned long int fib1 = fib(num1);
unsigned long int fib2 = fib(num2);
unsigned long int sum = fib1 + fib2;
// Prepare output string
char output[1024];
int len = snprintf(output, sizeof(output), "Fibonacci(%lu) + Fibonacci(%lu) = %lu + %lu = %lu\n", num1, num2, fib1, fib2, sum);
// Write to stdout
write(1, output, len);
// 清理内存
freeDataNodes(dataList);
return 0;
}

@ -0,0 +1,68 @@
{
"active": true,
"name": "work",
"path": "work_wasm.so",
"port": 10000,
"relative-deadline-us": 50000,
"argsize": 1,
"priority": 1,
"pre_module_count": 0,
"next_modules": ["work2", "work3"],
"http-req-headers": [],
"http-req-content-type": "text/plain",
"http-req-size": 1048776,
"http-resp-headers": [],
"http-resp-size": 1048776,
"http-resp-content-type": "text/plain"
},
{
"active": true,
"name": "work2",
"path": "work_wasm.so",
"port": 10001,
"relative-deadline-us": 50000,
"argsize": 1,
"priority": 1,
"pre_module_count": 1,
"next_modules": ["work4"],
"http-req-headers": [],
"http-req-content-type": "text/plain",
"http-req-size": 1048776,
"http-resp-headers": [],
"http-resp-size": 1048776,
"http-resp-content-type": "text/plain"
},
{
"active": true,
"name": "work3",
"path": "work_wasm.so",
"port": 10002,
"relative-deadline-us": 50000,
"argsize": 1,
"priority": 1,
"pre_module_count": 1,
"next_modules": ["work4"],
"http-req-headers": [],
"http-req-content-type": "text/plain",
"http-req-size": 1048776,
"http-resp-headers": [],
"http-resp-size": 1048776,
"http-resp-content-type": "text/plain"
},
{
"active": true,
"name": "work4",
"path": "fibonacciadd_wasm.so",
"port": 10003,
"relative-deadline-us": 50000,
"argsize": 1,
"priority": 1,
"pre_module_count": 2,
"next_modules": [],
"http-req-headers": [],
"http-req-content-type": "text/plain",
"http-req-size": 1048776,
"http-resp-headers": [],
"http-resp-size": 1048776,
"http-resp-content-type": "text/plain"
}

@ -0,0 +1,46 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define OUTPUT_BUFFER_SIZE (1024 * 5) // 5KB
int main() {
char *data = (char *)malloc(10 * 1024); // Allocate 10KB
if (!data) {
fprintf(stderr, "Failed to allocate memory.\n");
return 1;
}
ssize_t bytesRead = read(STDIN_FILENO, data, 10 * 1024);
if (bytesRead == -1) {
fprintf(stderr, "Failed to read data from file.\n");
free(data);
return 1;
}
// Create a combined buffer to hold the output
char *combined_output = malloc(2 * OUTPUT_BUFFER_SIZE + 50); // 50 extra bytes for text and safety
if (!combined_output) {
fprintf(stderr, "Failed to allocate memory for combined output.\n");
free(data);
return 1;
}
// Format the output in a single buffer
int offset = sprintf(combined_output, "Buffer 1 (First 5KB): ");
memcpy(combined_output + offset, data, OUTPUT_BUFFER_SIZE);
offset += OUTPUT_BUFFER_SIZE;
offset += sprintf(combined_output + offset, " Buffer 2 (Second 5KB): ");
memcpy(combined_output + offset, data + OUTPUT_BUFFER_SIZE, OUTPUT_BUFFER_SIZE);
// Print everything in one go
fwrite(combined_output, sizeof(char), offset + OUTPUT_BUFFER_SIZE, stdout);
printf("\n");
// Clean up
free(data);
free(combined_output);
return 0;
}

@ -2703,7 +2703,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.4"
"version": "3.1.undefined"
}
},
"nbformat": 4,

@ -1 +1,2 @@
sudo chsh -s /bin/bash xiaosuGW
sudo chsh -s /bin/bash hai

@ -0,0 +1,368 @@
{
"active": true,
"name": "resize1",
"path": "resize_wasm.so",
"port": 10000,
"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": "png2bmp1",
"path": "C-Image-Manip_wasm.so",
"port": 10001,
"relative-deadline-us": 78574,
"argsize": 1,
"http-req-headers": [],
"http-req-content-type": "image/png",
"http-req-size": 4096000,
"http-resp-headers": [],
"http-resp-size": 4096000,
"http-resp-content-type": "image/bmp"
},
{
"active": true,
"name": "cifar10_1",
"path": "cifar10_wasm.so",
"port": 10002,
"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": "resize2",
"path": "resize_wasm.so",
"port": 10003,
"relative-deadline-us": 192762,
"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": "png2bmp2",
"path": "C-Image-Manip_wasm.so",
"port": 10004,
"relative-deadline-us": 192762,
"argsize": 1,
"http-req-headers": [],
"http-req-content-type": "image/png",
"http-req-size": 4096000,
"http-resp-headers": [],
"http-resp-size": 4096000,
"http-resp-content-type": "image/bmp"
},
{
"active": true,
"name": "cifar10_2",
"path": "cifar10_wasm.so",
"port": 10005,
"relative-deadline-us": 192762,
"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": "resize3",
"path": "resize_wasm.so",
"port": 10006,
"relative-deadline-us": 16346,
"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": "png2bmp3",
"path": "C-Image-Manip_wasm.so",
"port": 10007,
"relative-deadline-us": 16346,
"argsize": 1,
"http-req-headers": [],
"http-req-content-type": "image/png",
"http-req-size": 4096000,
"http-resp-headers": [],
"http-resp-size": 4096000,
"http-resp-content-type": "image/bmp"
},
{
"active": true,
"name": "cifar10_3",
"path": "cifar10_wasm.so",
"port": 10008,
"relative-deadline-us": 16346,
"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": "resize4",
"path": "resize_wasm.so",
"port": 10009,
"relative-deadline-us": 47824,
"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": "png2bmp4",
"path": "C-Image-Manip_wasm.so",
"port": 10010,
"relative-deadline-us": 47824,
"argsize": 1,
"http-req-headers": [],
"http-req-content-type": "image/png",
"http-req-size": 4096000,
"http-resp-headers": [],
"http-resp-size": 4096000,
"http-resp-content-type": "image/bmp"
},
{
"active": true,
"name": "cifar10_4",
"path": "cifar10_wasm.so",
"port": 10011,
"relative-deadline-us": 47824,
"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": "resize5",
"path": "resize_wasm.so",
"port": 10012,
"relative-deadline-us": 392870,
"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": "png2bmp5",
"path": "C-Image-Manip_wasm.so",
"port": 10013,
"relative-deadline-us": 392870,
"argsize": 1,
"http-req-headers": [],
"http-req-content-type": "image/png",
"http-req-size": 4096000,
"http-resp-headers": [],
"http-resp-size": 4096000,
"http-resp-content-type": "image/bmp"
},
{
"active": true,
"name": "cifar10_5",
"path": "cifar10_wasm.so",
"port": 10014,
"relative-deadline-us": 392870,
"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": "resize6",
"path": "resize_wasm.so",
"port": 10015,
"relative-deadline-us": 963810,
"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": "png2bmp6",
"path": "C-Image-Manip_wasm.so",
"port": 10016,
"relative-deadline-us": 963810,
"argsize": 1,
"http-req-headers": [],
"http-req-content-type": "image/png",
"http-req-size": 4096000,
"http-resp-headers": [],
"http-resp-size": 4096000,
"http-resp-content-type": "image/bmp"
},
{
"active": true,
"name": "cifar10_6",
"path": "cifar10_wasm.so",
"port": 10017,
"relative-deadline-us": 963810,
"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": "resize7",
"path": "resize_wasm.so",
"port": 10018,
"relative-deadline-us": 81730,
"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": "png2bmp7",
"path": "C-Image-Manip_wasm.so",
"port": 10019,
"relative-deadline-us": 81730,
"argsize": 1,
"http-req-headers": [],
"http-req-content-type": "image/png",
"http-req-size": 4096000,
"http-resp-headers": [],
"http-resp-size": 4096000,
"http-resp-content-type": "image/bmp"
},
{
"active": true,
"name": "cifar10_7",
"path": "cifar10_wasm.so",
"port": 10020,
"relative-deadline-us": 81730,
"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": "resize8",
"path": "resize_wasm.so",
"port": 10021,
"relative-deadline-us": 239120,
"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": "png2bmp8",
"path": "C-Image-Manip_wasm.so",
"port": 10022,
"relative-deadline-us": 239120,
"argsize": 1,
"http-req-headers": [],
"http-req-content-type": "image/png",
"http-req-size": 4096000,
"http-resp-headers": [],
"http-resp-size": 4096000,
"http-resp-content-type": "image/bmp"
},
{
"active": true,
"name": "cifar10_8",
"path": "cifar10_wasm.so",
"port": 10023,
"relative-deadline-us": 239120,
"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
},

@ -1,14 +0,0 @@
{
"active": true,
"name": "work1k",
"path": "work1k_wasm.so",
"port": 10000,
"relative-deadline-us": 50000,
"argsize": 1,
"http-req-headers": [],
"http-req-content-type": "text/plain",
"http-req-size": 1200,
"http-resp-headers": [],
"http-resp-size": 1200,
"http-resp-content-type": "text/plain"
}

Binary file not shown.

@ -26,5 +26,6 @@ main(void)
else
write(1, d, r);
free(d);
return 0;
}

@ -19,6 +19,9 @@ jsmn:
mkdir -p ${DIST_PREFIX}/include/
cp jsmn/jsmn.h ${DIST_PREFIX}/include/
hashmap: hashmap/hashmap.c
cd hashmap; $(CC) $(CFLAGS) -I. -c hashmap.c; mv hashmap.o ${DIST_PREFIX}/lib/; cp hashmap.h ${DIST_PREFIX}/include/
clean:
make -C ck uninstall
rm -rf ${DIST_PREFIX}

@ -0,0 +1 @@
Subproject commit 1c139923fe08f36143ecc0ba37cd674684f87f9c

Binary file not shown.

@ -0,0 +1,70 @@
#include "../include/map.h"
#include <stdio.h>
typedef struct {
int id;
char name[100];
float salary;
} Employee;
int main() {
// 初始化哈希表
struct hashmap myMap;
map_init(&myMap);
// 创建并初始化一些 Employee 结构体
Employee *alice = malloc(sizeof(Employee));
alice->id = 1;
strcpy(alice->name, "Alice");
alice->salary = 50000.0;
Employee *bob = malloc(sizeof(Employee));
bob->id = 2;
strcpy(bob->name, "Bob");
bob->salary = 52000.0;
// 将 Employee 结构体存入哈希表
char *key1 = "employee1";
map_set(&myMap, key1, strlen(key1), alice, sizeof(Employee*), false);
char *key2 = "employee2";
map_set(&myMap, key2, strlen(key2), bob, sizeof(Employee*), true);
// 尝试从哈希表中检索 Employee
uint32_t ret_value_len;
Employee *retrieved_employee = (Employee *)map_get(&myMap, key1, strlen(key1), &ret_value_len);
if (retrieved_employee) {
printf("Retrieved Employee: %s, ID: %d, Salary: %.2f\n",
retrieved_employee->name, retrieved_employee->id, retrieved_employee->salary);
} else {
printf("Employee not found.\n");
}
alice->id = 12;
char *key = "employee1";
strcat(alice->name, key);
retrieved_employee = (Employee *)map_get(&myMap, key1, strlen(key1), &ret_value_len);
if (retrieved_employee) {
printf("Retrieved Employee: %s, ID: %d, Salary: %.2f\n",
retrieved_employee->name, retrieved_employee->id, retrieved_employee->salary);
} else {
printf("Employee not found.\n");
}
uint64_t value1 = 20, value2 = 30;
char *key3 = "test1";
char *key4 = "test2";
map_set(&myMap, key3, strlen(key3), &value1, sizeof(uint64_t), true);
uint32_t *value = (uint32_t *)map_get(&myMap, key3, strlen(key3), &ret_value_len);
if (value) printf("Retrieved value: %d\n", *value); else printf("Value not found.\n");
value1 ++;
value = (uint32_t *)map_get(&myMap, key3, strlen(key3), &ret_value_len);
if (value) printf("Retrieved value: %d\n", *value); else printf("Value not found.\n");
map_upsert(&myMap, key3, strlen(key3), &value1, sizeof(uint64_t));
value = (uint32_t *)map_get(&myMap, key3, strlen(key3), &ret_value_len);
if (value) printf("Retrieved value: %d\n", *value); else printf("Value not found.\n");
free(alice);
free(bob);
return 0;
}

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save