Skip to content

Commit 3a1b12b

Browse files
committed
Update Rust example and convert C to C++ storage example
1 parent 4fcc6bf commit 3a1b12b

File tree

8 files changed

+108
-26
lines changed

8 files changed

+108
-26
lines changed

guest/rust_storage/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ edition = "2021"
77
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
88

99
[dependencies]
10+
emballoc = "0.3.0"
1011
libc = "0.2"
1112

1213
[profile.release]

guest/rust_storage/src/main.rs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1+
#[global_allocator]
2+
static ALLOCATOR: emballoc::Allocator<4096> = emballoc::Allocator::new();
3+
extern crate alloc;
4+
15
use std::arch::asm;
2-
extern "C" { fn remote_function(arg: fn(i32) -> i32, value: i32) -> i32; }
36
use std::process::ExitCode;
7+
extern "C" { fn remote_function(arg: fn(i32) -> i32, value: i32) -> i32; }
8+
// Perform a remote allocation with a local allocator
9+
extern "C" { fn remote_allocation(fsbase: u64, alloc: fn() -> Vec<i32>) -> Vec<i32>; }
410

511
fn double_int(input: i32) -> i32 {
612
return input * 2;
@@ -30,11 +36,34 @@ fn set_callback(name: &str, cb: extern "C" fn(i32) -> i32) {
3036
}
3137
}
3238

39+
fn get_current_fsbase() -> u64 {
40+
let fsbase: u64;
41+
unsafe {
42+
asm!(
43+
"rdfsbase {}",
44+
out(reg) fsbase,
45+
);
46+
}
47+
return fsbase;
48+
}
49+
fn alloc_vec() -> Vec<i32> {
50+
let mut v = Vec::with_capacity(10);
51+
for i in 0..10 {
52+
v.push(i * 10);
53+
}
54+
return v;
55+
}
56+
3357
fn main() -> ExitCode
3458
{
3559
println!("Hello, world!");
3660
let result = unsafe { remote_function(double_int, 21) };
3761
println!("Result from remote function: {}", result);
62+
63+
let vec = unsafe { remote_allocation(get_current_fsbase(), alloc_vec) };
64+
println!("Received vector from remote allocation: {:?}", vec);
65+
66+
// Register callbacks
3867
set_callback("do_calculation", do_calculation);
3968
set_callback("do_nothing", do_nothing);
4069
return ExitCode::from(result as u8);

guest/rust_storage/storage_program/src/main.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::process::ExitCode;
22
use std::sync::{LazyLock, Mutex};
3+
use std::arch::asm;
34
static ARRAY: LazyLock<Mutex<Vec<i32>>> = LazyLock::new(|| Mutex::new(vec![]));
45

56
#[no_mangle]
@@ -10,6 +11,24 @@ extern "C" fn remote_function(arg: fn(i32) -> i32, value: i32) -> i32 {
1011
return arg(value);
1112
}
1213

14+
fn set_fsbase(fsbase: u64) {
15+
unsafe {
16+
asm!(
17+
"wrfsbase {}",
18+
in(reg) fsbase,
19+
);
20+
}
21+
}
22+
23+
#[no_mangle]
24+
extern "C" fn remote_allocation(fsbase: u64, alloc: fn() -> Vec<i32>) -> Vec<i32> {
25+
// Set the FSBASE to the provided value
26+
set_fsbase(fsbase);
27+
// Call the allocator function
28+
return alloc();
29+
//return vec![42, 43, 44];
30+
}
31+
1332
fn main() -> ExitCode
1433
{
1534
println!("Hello, Storage World!");

guest/storage/build.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
set -v
2-
gcc-12 -static -O2 -Wl,-Ttext-segment=0x44000000 storage.c -o storage
2+
clang++-20 -static -O2 -std=c++20 -Wl,-Ttext-segment=0x44000000 storage.cpp -o storage
33

44
objcopy -w --extract-symbol --strip-symbol=!remote* --strip-symbol=* storage storage.syms
5-
gcc-12 -static -O2 -Wl,--just-symbols=storage.syms main.c -o main
5+
clang++-20 -static -O2 -std=c++20 -Wl,--just-symbols=storage.syms main.cpp -o main
Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#include <stdio.h>
2-
extern int remote_function(int(*callback)(int), int value);
2+
extern "C" int remote_function(int(*callback)(int), int value);
33

44
static int double_int(int value)
55
{
@@ -8,7 +8,7 @@ static int double_int(int value)
88

99
int main()
1010
{
11-
printf("Jumping to %p\n", &remote_function);
11+
printf("Hello from Main VM!\n");
1212
fflush(stdout);
1313
for (int i = 0; i < 10; i++) {
1414
const int val = remote_function(double_int, 21);
@@ -17,12 +17,8 @@ int main()
1717
return 0;
1818
}
1919

20-
int do_calculation(int value)
20+
extern "C" int do_calculation(int value)
2121
{
2222
return remote_function(double_int, value);
2323
}
24-
25-
int simple_calculation(int value)
26-
{
27-
return value;
28-
}
24+
extern "C" void do_nothing(int) { }
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
#include <stdio.h>
22
#include <unistd.h>
33

4-
extern int remote_function(int (*arg)(int), int value)
4+
extern "C" int remote_function(int (*arg)(int), int value)
55
{
6-
write(1, "In remote_function\n", 20);
6+
//write(1, "In remote_function\n", 20);
77
return arg(value);
88
}
99

src/storage.cpp

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -215,35 +215,46 @@ int main(int argc, char** argv)
215215
assert(vm.has_remote());
216216

217217
/* Measure call overhead */
218+
uint64_t do_nothing_addr = 0x0;
219+
uint64_t do_calculation_addr = 0x0;
218220
auto do_it = callback_address.find("do_nothing");
219221
if (do_it == callback_address.end()) {
220-
fprintf(stderr, "Error: no do_nothing() in guest\n");
221-
exit(1);
222+
do_nothing_addr = master_vm.address_of("do_nothing");
223+
if (do_nothing_addr == 0x0) {
224+
fprintf(stderr, "Error: no do_nothing() in guest\n");
225+
exit(1);
226+
}
227+
} else {
228+
do_nothing_addr = do_it->second;
222229
}
223230
auto calc_it = callback_address.find("do_calculation");
224231
if (calc_it == callback_address.end()) {
225-
fprintf(stderr, "Error: no do_calculation() in guest\n");
226-
exit(1);
232+
do_calculation_addr = master_vm.address_of("do_calculation");
233+
if (do_calculation_addr == 0x0) {
234+
fprintf(stderr, "Error: no do_calculation() in guest\n");
235+
exit(1);
236+
}
237+
} else {
238+
do_calculation_addr = calc_it->second;
227239
}
228-
auto call_overhead = timed_action([&] {
229-
for (int i = 0; i < 100; i++)
230-
vm.vmcall(do_it->second, 5.0f, 21);
231-
}) / 100.0;
232-
printf("Call overhead: %.2fus\n", call_overhead * 1e6);
240+
TimedResult call_overhead = timed_action(1000, [&] {
241+
vm.vmcall(do_nothing_addr, 5.0f, 21);
242+
});
243+
printf("Call overhead: %.2fus\n", call_overhead.median * 1e6);
233244

234245
/* Call 'do_calculation' with 21 as argument */
235-
printf("Calling do_calculation() @ 0x%lX\n", calc_it->second);
246+
printf("Calling do_calculation() @ 0x%lX\n", do_calculation_addr);
236247
for (int i = 0; i < 50; i++)
237-
vm.vmcall(calc_it->second, 21);
248+
vm.vmcall(do_calculation_addr, 21);
238249
TimedResult fork_tdiff = timed_action(15000, [&] {
239-
vm.vmcall(calc_it->second, 21);
250+
vm.vmcall(do_calculation_addr, 21);
240251
});
241252
if (vm.remote_connection_count() < 15000) {
242253
fprintf(stderr, "Error: only %u remote connections were made, expected 500\n",
243254
vm.remote_connection_count());
244255
exit(1);
245256
}
246-
fork_tdiff -= call_overhead;
257+
fork_tdiff -= call_overhead.median;
247258
printf("* Remote call time: avg %.2fus med %.2fus p50 %.2fus p90 %.2fus p99 %.2fus min %.2fus max %.2fus\n",
248259
fork_tdiff.average * 1e6, fork_tdiff.median * 1e6,
249260
fork_tdiff.p50 * 1e6, fork_tdiff.p90 * 1e6,

storage.sh

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#!/bin/bash
2+
set -e
3+
pushd build
4+
make -j8
5+
popd
6+
# We can't pass a symlink to the main VM, since we allow dynamic linker loading
7+
# there, and TinyKVM refuses to use symlinks for security reasons.
8+
9+
# --rust:
10+
# ./build/storagekvm guest/rust_storage/target/release/demo guest/rust_storage/storage
11+
# --cpp
12+
# ./build/storagekvm guest/storage/main guest/storage/storage
13+
14+
# Parse args
15+
if [ "$1" = "--rust" ]; then
16+
MAIN=guest/rust_storage/target/release/demo
17+
SECONDARY=guest/rust_storage/storage
18+
elif [ "$1" = "--cpp" ]; then
19+
MAIN=guest/storage/main
20+
SECONDARY=guest/storage/storage
21+
else
22+
echo "Usage: $0 [--rust|--cpp]"
23+
exit 1
24+
fi
25+
26+
./build/storagekvm $MAIN $SECONDARY

0 commit comments

Comments
 (0)