Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
target
tinywasm
wasmtime-as-lib
image_content
image_content/*

.VSCodeCounter
.gdbinit
Expand Down
84 changes: 41 additions & 43 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,75 +1,73 @@
# AlloyStack

<!-- [![CI](https://github.com/anti-entropy123/mslibos/actions/workflows/main.yml/badge.svg)](https://github.com/anti-entropy123/mslibos/actions/workflows/main.yml) -->
[![CI](https://github.com/anti-entropy123/AlloyStack/actions/workflows/main.yml/badge.svg)](https://github.com/anti-entropy123/AlloyStack/actions/workflows/main.yml)

## 构建
## Abstract
AlloyStack is a library OS designed for serverless workflow applications. It reduces cold start latency through on-demand loading and optimizes intermediate data transfer overhead via reference passing. We provide user-friendly tools and scripts in the AlloyStack code repository to automate the
build and testing processes. This document guides users in reproducing the experimental results.

### 全部构建
## Artifact check-list

不使用 MPK:
* Program: AlloyStack
* Compilation: rustup toolchain (nightly-2023-12-01-x86_64-unknown-linux-gnu) and gcc (11.4.0)
* Run-time environment: Ubuntu 22.04
* Hardware: Intel x86 servers equipped with MPK

```bash
./scripts/build_all_common.sh
./scripts/build_user.sh
```
## Installation

使用 MPK
**Software dependencies**. To build AlloyStack’s LibOS and Rust functions, the toolchain must be installed via rustup. To build C and Python functions, gcc (version 11.4.0) need to be installed. To run automated tests and perform data analysis, [just](https://github.com/casey/just) and python3 need to be installed.

```bash
./scripts/build_all_common_mpk.sh
./scripts/build_user.sh mpk
```
AlloyStack and its benchmarks are \href{https://github.com/anti-entropy123/AlloyStack}{open-sourced} and can be obtained via git clone. The code repository is structured as follows:

### 单个构建

不使用 MPK:

```bash
./scripts/build_all_common.sh
cargo build --manifest-path user/<appname>/Cargo.toml
```

使用 MPK:

```bash
./scripts/build_all_common_mpk.sh
Cargo build --features mpk --manifest-path user/<appname>/Cargo.toml
AlloyStack/
|- libasvisor/ # source code of as-visor
|- as_std/ # source code of as-std
|- common_service/
\- ... # as-libos modules
|- user/
\- ... # source code of benchmarks
|- isol_config/
\- *.json # workflow specification files
|- fs_images/
\- *.img # file system images
```

## 增加新工作流

To run a new test application on AlloyStack, user need to develop functions in the `user/` directory. Then, edit the workflow specification files in the `isol_config/` directory to declare how functions compose the workflow, specify dependencies on LibOS modules, and define input parameters for functions. If the workflow involves reading datasets from files, the datasets must also be added to the file system image. Please use the following command to extract the provided image archive, which contains the source code for the Python benchmarks.

```bash
cargo run -p gen-file
vim config.json
mv config.json isol_config/[your-isol-name].json
AlloyStack$ just init
```

## 测试
Additionally, the repository of AlloyStack is integrated with GitHub Actions. Therefore, tools such as [act](https://github.com/nektos/act) can be used locally to quickly run some basic test cases via Docker.

### 全部测试
不使用 MPK:
## Evaluation
### Cold start latency

The cold start of AlloyStack can be categorized into two scenarios: enabling and disabling on-demand loading. The approximate cold start latency is measured using the execution time of `hello_world` and `load_all`, respectively. The following script can be used to automate the testing process.

```bash
./scripts/run_tests.sh
AlloyStack$ just cold_start_latency
```

使用 MPK:
### Intermediate Data Transfer Latency
Users can control the size of the data to be transferred (in bytes) via `user/data_size.config`. The following command can automatically run the test and output key result logs.

```bash
./scripts/run_tests.sh mpk
AlloyStack$ just data_transfer_latency
```

### 单个测试
### End-to-end latency

不使用 MPK:
The current implementation configures the parallelism of each function through the workflow specification file. Users can generate dataset files tailored to a specific parallelism level using the `scripts/gen_data.py` script. The size of the intermediate data in `Function Chain` can be adjusted via the `function_chain_data_size.config` file located in the `user/` directory. Running the following command will automatically complete data generation, function building, and end-to-end testing for `Word Count`, `Parallel Sorting`, and `Function Chain`.

```bash
cargo run -- --files isol_config/<workflowname>.json
AlloyStack$ just end_to_end_latency
```

使用 MPK:
The breakdown, P99 latency and resource consumption experiments are conducted based on variants of the aforementioned applications. To disable the on-demand loading mechanism, the workflow configuration file needs to be modified (e.g., `map_reduce_load_all.json`). To disable the reference-passing mechanism, the parameter `--features file-based` should be added when building functions. For experiments requiring concurrent request generation, we provide the load generator `p99tester` and `resourcetester`. The following script automatically switches these configuration options and runs the tests.

```bash
cargo run --features mpk -- --files isol_config/<workflowname>.json
```

AlloyStack$ just breakdown && just p99_latency && just resource_consume
```
3 changes: 2 additions & 1 deletion common_service/ruxfdtab/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ lazy_static = { version = "1.5.0", features = ["spin_no_std"] }
[features]
mpk = ["as_std/mpk"]
use-ramdisk = ["ruxfs/use-ramdisk", "ruxfs/full", "ruxdriver"]
lock = []
log = []

default = ["use-ramdisk"]
default = ["use-ramdisk", "lock"]
26 changes: 25 additions & 1 deletion common_service/ruxfdtab/src/as_apis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ extern crate alloc;
use std::path::PathBuf;

use alloc::vec;
use as_std::{libos::libos};
use as_std::libos::libos;
use spin::Mutex;

use crate::{
fd_ops::{close_file_like, get_file_like},
Expand Down Expand Up @@ -93,9 +94,15 @@ lazy_static::lazy_static! {
};
}

#[cfg(feature = "lock")]
static GLOBAL_LOCK: Mutex<()> = Mutex::new(());

#[no_mangle]
pub fn open(path: &str, flags: OpenFlags, mode: OpenMode) -> FdtabResult<Fd> {
let _exec = *MUST_EXIC;
#[cfg(feature = "lock")]
let _lock = GLOBAL_LOCK.lock();

#[cfg(feature = "log")]
{
println!("ruxfdtab: open path={:?}", path);
Expand Down Expand Up @@ -128,6 +135,9 @@ pub fn open(path: &str, flags: OpenFlags, mode: OpenMode) -> FdtabResult<Fd> {
#[no_mangle]
pub fn write(fd: Fd, buf: &[u8]) -> FdtabResult<Size> {
let _exec = *MUST_EXIC;
#[cfg(feature = "lock")]
let _lock = GLOBAL_LOCK.lock();

// libos!(stdout(format!("fd: {}, buf: {:?}", fd, buf).as_bytes()));
let f = get_file_like(fd)?;

Expand All @@ -144,6 +154,9 @@ pub fn write(fd: Fd, buf: &[u8]) -> FdtabResult<Size> {
#[no_mangle]
pub fn read(fd: Fd, buf: &mut [u8]) -> FdtabResult<Size> {
let _exec = *MUST_EXIC;
#[cfg(feature = "lock")]
let _lock = GLOBAL_LOCK.lock();

get_file_like(fd)?
.read(buf)
.map_err(|e| FdtabError::RuxfsError(e.to_string()))
Expand All @@ -152,12 +165,18 @@ pub fn read(fd: Fd, buf: &mut [u8]) -> FdtabResult<Size> {
#[no_mangle]
pub fn close(fd: Fd) -> FdtabResult<()> {
let _exec = *MUST_EXIC;
#[cfg(feature = "lock")]
let _lock = GLOBAL_LOCK.lock();

close_file_like(fd)
}

#[no_mangle]
pub fn lseek(fd: Fd, pos: u32) -> FdtabResult<()> {
let _exec = *MUST_EXIC;
#[cfg(feature = "lock")]
let _lock = GLOBAL_LOCK.lock();

fs::File::from_fd(fd)?
.inner
.lock()
Expand All @@ -170,6 +189,9 @@ pub fn lseek(fd: Fd, pos: u32) -> FdtabResult<()> {
#[no_mangle]
pub fn stat(fd: Fd) -> FdtabResult<Stat> {
let _exec = *MUST_EXIC;
#[cfg(feature = "lock")]
let _lock = GLOBAL_LOCK.lock();

let stat = fs::File::from_fd(fd)?
.stat()
.map_err(|e| FdtabError::RuxfsError(e.to_string()))?;
Expand All @@ -183,6 +205,8 @@ pub fn stat(fd: Fd) -> FdtabResult<Stat> {
#[no_mangle]
pub fn readdir(path: &str) -> FdtabResult<Vec<DirEntry>> {
let _exec = *MUST_EXIC;
#[cfg(feature = "lock")]
let _lock = GLOBAL_LOCK.lock();
#[cfg(feature = "log")]
println!("[DEBUG] ruxfs read_dir: {:?}", path);

Expand Down
48 changes: 20 additions & 28 deletions common_service/socket/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion common_service/socket/src/apis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ pub fn addrinfo(name: &str) -> SmoltcpResult<Ipv4Addr> {
let dns_socket = sockets.get_mut::<dns::Socket>(dns_handle);
let query = dns_socket
.start_query(iface.context(), name, DnsQueryType::A)
.map_err(|e| SmoltcpError::SmoltcpErr(e.to_string()))?;
.map_err(|e| {
println!("query err: {}", e);
SmoltcpError::DNSQueryFailed
})?;

(dns_handle, query)
};
Expand Down
Binary file modified fs_images/fatfs.zip
Binary file not shown.
Loading
Loading