GitHub - NobodyXu/aspawn: Asynchronous and more versatile replacement of posix_spawn (original) (raw)

aspawn

C/C++ CI

Asynchronous and more versatile replacement of posix_spawn

Intro

aspawn implements the idea from avfork, enabling user to do posix_spawn in an asynchronous way by making syscall directly via pure_syscall implemented in my library that does not use any global/thread local variable at all.

My aspawn has signature:

struct Stack_t { void *addr; size_t size; };

/**

/**

By returning the write end of the CLOEXEC pipefd, user of this library is able to receive error message/check whether the child process has done using cached_stack so that aspawn can reuse cached_stack.

It also allows user to pass arbitary data in the stack via allocate_obj_on_stack, thus user does not have to allocate them separately on heap.

To use a syscall, you need to include syscall/syscall.h, which defines the syscall routine used by the child process includingfind_exe, psys_execve and psys_execveat.

User will be able to reuse stack by polling the fd returned by aspawn and wait for it to hup.

Compare to posix_spawn, aspawn has 3 advantages:

Example code

Examples can be seen here

Platform support

Currently, it only supports x86-64 modern linux (>= 4.0), but ports can be easily made by modifing syscall/,create_pipe/create_pipe.c and clone_internal/

Benchmark

Responsive benchmark

Responsive comparison between posix_spawn and aspawn, source code (benchmarking is done via google/benchmark:

$ ll -h bench_aspawn_responsiveness.out -rwxrwxr-x 1 nobodyxu nobodyxu 254K Oct 2 15:02 bench_aspawn_responsiveness.out*

$ uname -a Linux pop-os 5.4.0-7642-generic #46159862870720.04~040157c-Ubuntu SMP Fri Aug 28 18:02:16 UTC x86_64 x86_64 x86_64 GNU/Linux

$ ./a.out 2020-10-02T15:02:45+10:00 Running ./bench_aspawn_responsiveness.out Run on (12 X 4100 MHz CPU s) CPU Caches: L1 Data 32 KiB (x6) L1 Instruction 32 KiB (x6) L2 Unified 256 KiB (x6) L3 Unified 9216 KiB (x1) Load Average: 0.31, 0.36, 0.32

Benchmark Time CPU Iterations

BM_aspawn_no_reuse 18009 ns 17942 ns 38943 BM_aspawn/threads:1 14500 ns 14446 ns 48339 BM_vfork_with_shared_stack 46545 ns 16554 ns 44027 BM_fork 54583 ns 54527 ns 12810 BM_posix_spawn 125061 ns 29091 ns 24483

The column "Time" is measured in terms of system clock, while "CPU" is measured in terms of per-process CPU time.

Throughput benchmark

Since aspawn allows user to do anything in the vforked child via aspawn_fn, it makes no sense to benchmark how many processes can aspawn created as it depends on user provided argument fn.

Build and Install

Make sure that you have installed make, clang lld and llvm-ar.

Then run make -j $(nproc) to build the project, sudo make install to install project to /usr/local/.

Testing

Make sure you have installed all depedencies listed above for building this project, then run make test -j $(nproc)

Contributing to this project

Any commits on this project will be welcome!

It would be even better if you can help me improve test coverages by adding more unit tests or port this project to other platform (e.g. arm, mips).

Contributors

Thank you for people who contributed to this project: