Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add spawn scheduler docs #125

Merged
merged 5 commits into from
Nov 15, 2024
Merged
Changes from 3 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
59 changes: 50 additions & 9 deletions src/syscalls/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -590,14 +590,55 @@ pub struct SpawnArgs {
/// The parent process calls the Spawn system call, which creates a new process (a child process) that is an
/// independent ckb-vm instance. It's important to note that the parent process will not be blocked by the child
/// process as a result of this syscall.
/// Note: available after ckb2023.
/// Note: available after ckb 2nd hardfork.
///
/// # Arguments
///
/// * `index`, `source`, `bounds` and `place` - same as exec.
/// * `spgs` - spawn arguments.
///
/// Returns success or a syscall error.
///
/// # Scheduler Algorithm V1
///
/// This document describes the design and functionality of a scheduler algorithm, covering process states, system call
/// behavior, message handling, and priority rules. The scheduler manages virtual processes, transitioning them through
/// various states based on operations and interactions, to ensure efficient scheduling.
///
/// # Thread States
///
/// Each process within this scheduler has one of the following six states:
/// * Runnable: The process is ready to execute.
/// * Running: The process is running.
/// * Terminated: The process has completed its execution.
/// * WaitForRead: The process is waiting for data to be available for it to read.
/// * WaitForWrite: The process is waiting for another process to read data it wants to write.
/// * WaitForExit: The process is waiting for another process to exit before it can continue.
///
/// # System Calls and State Transitions
///
/// Specific system calls are responsible for changing the state of a process within this scheduler:
/// * spawn: Creates a new process, initializing it in the Runnable state.
/// * read: Attempts to read data from a file descriptor. If data is unavailable, the process state changes to
mohanson marked this conversation as resolved.
Show resolved Hide resolved
/// WaitForRead.
/// * write: Attempts to write data to a file descriptor. If the operation is blocked due to data needing to be read by
mohanson marked this conversation as resolved.
Show resolved Hide resolved
/// another process, the process enters the WaitForWrite state.
/// * wait: Waits for a target process to exit. Once the target process has terminated, the waiting process transitions
/// to Runnable.
///
/// # IO Handling and State Recovery
///
/// IO handling allows processes in certain states to transition back to Runnable when specific conditions are met:
/// * A WaitForRead process becomes Runnable once the needed data has been read successfully.
/// * A WaitForWrite process transitions to Runnable once its data has been successfully read by another process.
///
/// # Process Priority
///
/// The scheduler assigns incremental IDs to processes, establishing an execution order:
/// * The root process has an ID of 0.
/// * When multiple processes are in the Runnable state, the scheduler selects the process with the lowest ID to execute
/// first. This ensures a predictable and fair ordering of execution for processes ready to run. The selected
/// process status is changed to Running, and it continues to run until its status is changed.
mohanson marked this conversation as resolved.
Show resolved Hide resolved
pub fn spawn(
index: usize,
source: Source,
Expand Down Expand Up @@ -629,7 +670,7 @@ pub fn spawn(
}

/// The syscall pauses until the execution of a process specified by pid has ended.
/// Note: available after ckb2023.
/// Note: available after ckb 2nd hardfork.
///
/// # Arguments
///
Expand All @@ -647,14 +688,14 @@ pub fn wait(pid: u64) -> Result<i8, SysError> {
}

/// This syscall is used to get the current process id. Root process ID is 0.
/// Note: available after ckb2023.
/// Note: available after ckb 2nd hardfork.
pub fn process_id() -> u64 {
unsafe { syscall(0, 0, 0, 0, 0, 0, 0, SYS_PROCESS_ID) }
}

/// This syscall create a pipe with read-write pair of file descriptions. The file descriptor with read permission is
/// located at fds[0], and the corresponding file descriptor with write permission is located at fds[1].
/// Note: available after ckb2023.
/// Note: available after ckb 2nd hardfork.
pub fn pipe() -> Result<(u64, u64), SysError> {
let mut fds: [u64; 2] = [0, 0];
let ret = unsafe { syscall(fds.as_mut_ptr() as u64, 0, 0, 0, 0, 0, 0, SYS_PIPE) };
Expand All @@ -667,7 +708,7 @@ pub fn pipe() -> Result<(u64, u64), SysError> {

/// This syscall reads data from a pipe via a file descriptor. The syscall Read attempts to read up to value pointed by
/// length bytes from file descriptor fd into the buffer, and the actual length of data read is returned.
/// Note: available after ckb2023.
/// Note: available after ckb 2nd hardfork.
pub fn read(fd: u64, buffer: &mut [u8]) -> Result<usize, SysError> {
let mut l: u64 = buffer.len() as u64;
let ret = unsafe {
Expand All @@ -693,7 +734,7 @@ pub fn read(fd: u64, buffer: &mut [u8]) -> Result<usize, SysError> {

/// This syscall writes data to a pipe via a file descriptor. The syscall Write writes up to value pointed by length
/// bytes from the buffer, and the actual length of data written is returned.
/// Note: available after ckb2023.
/// Note: available after ckb 2nd hardfork.
pub fn write(fd: u64, buffer: &[u8]) -> Result<usize, SysError> {
let mut l: u64 = buffer.len() as u64;
let ret = unsafe {
Expand All @@ -719,7 +760,7 @@ pub fn write(fd: u64, buffer: &[u8]) -> Result<usize, SysError> {

/// This syscall retrieves the file descriptors available to the current process, which are passed in from the parent
/// process. These results are copied from the inherited_fds parameter of the Spawn syscall.
/// Note: available after ckb2023.
/// Note: available after ckb 2nd hardfork.
pub fn inherited_fds(fds: &mut [u64]) -> u64 {
let mut l: u64 = fds.len() as u64;
unsafe {
Expand All @@ -739,7 +780,7 @@ pub fn inherited_fds(fds: &mut [u64]) -> u64 {

/// This syscall manually closes a file descriptor. After calling this, any attempt to read/write the file descriptor
/// pointed to the other end would fail.
/// Note: available after ckb2023.
/// Note: available after ckb 2nd hardfork.
pub fn close(fd: u64) -> Result<(), SysError> {
let ret = unsafe { syscall(fd, 0, 0, 0, 0, 0, 0, SYS_CLOSE) };
match ret {
Expand All @@ -759,7 +800,7 @@ pub fn close(fd: u64) -> Result<(), SysError> {
/// * `index` - index of cell
/// * `source` - source of cell
///
/// Note: available after ckb2023.
/// Note: available after ckb 2nd hardfork.
pub fn load_block_extension(
buf: &mut [u8],
offset: usize,
Expand Down