-
Notifications
You must be signed in to change notification settings - Fork 6
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
Support new spawn #13
Merged
Merged
Changes from 4 commits
Commits
Show all changes
36 commits
Select commit
Hold shift + click to select a range
a857ffa
Support spawn
joii2020 cbf704d
Remove unused deps
joii2020 24e5295
Fix warning: cargo clippy
joii2020 6162144
Add Pin for Global data
joii2020 a5687b6
Fix with value naming
joii2020 ad3cd0f
Add testcase
joii2020 72a4f71
Add CI : testcase
joii2020 a68a701
Refactore: process rename to vm
joii2020 975fbbe
Refactore: Remove struct Spawn
joii2020 84e07fe
Check fd when spawn
joii2020 848ac9b
Fix bug: spawn multiple reads
joii2020 af004df
Add ckb-std-wrapper on tests
joii2020 fcb59f9
Clean global data when before ckb_main
joii2020 9c00d32
Update deps git:rev
joii2020 3fa8a38
SpawnCmd using num_derive
joii2020 00001a4
Add testcase: Check invaild fd when spawn
joii2020 27db927
Refactory spawn parent and child
joii2020 7422483
Add testcase: spawn return max vms
joii2020 f6236ec
Add testcase : spawn wait exit
joii2020 79b8dd9
Add testcase
joii2020 513f90e
Add test: r/w failed
joii2020 5e070fd
Add spawn_cases (from ckb), doing
joii2020 6946164
vm_info.rs renamt to simulator_context
joii2020 bf51d2c
VmID and TxID move to simulator_context
joii2020 a8f1419
TxID rename to SimID
joii2020 1129816
Refactory
joii2020 437c5b8
Rewrite the spawn scheduling related code
joii2020 63ef979
Add testcase
joii2020 f3255bf
Add test and fix bug (about spawn close)
joii2020 b623f11
Fix cargo clippy warngin
joii2020 a977a96
Add testcase check_pid
joii2020 6fa43e1
Remove debugging code and unused comments
joii2020 f41ea4a
Adjust spawn io return order
joii2020 4e77e89
LLVM update to 18
joii2020 6b206dd
Use define to replace magic numbers that return error
joii2020 2bcd67c
Improve assert_vm_version logic
joii2020 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
use crate::process_info::TxContext; | ||
use std::{ | ||
collections::HashMap, | ||
ffi::c_void, | ||
pin::Pin, | ||
sync::{Mutex, MutexGuard}, | ||
}; | ||
|
||
lazy_static! { | ||
static ref GLOBAL_DATA: Pin<Box<Mutex<GlobalData>>> = Pin::new(Box::default()); | ||
} | ||
static mut GLOBAL_DATA_PTR: *mut Mutex<GlobalData> = std::ptr::null_mut(); | ||
|
||
#[derive(Default, PartialEq, Eq, Clone, Hash, Debug)] | ||
pub struct TxID(u64); | ||
impl From<u64> for TxID { | ||
fn from(value: u64) -> Self { | ||
Self(value) | ||
} | ||
} | ||
impl From<TxID> for u64 { | ||
fn from(value: TxID) -> Self { | ||
value.0 | ||
} | ||
} | ||
impl TxID { | ||
fn next(&mut self) -> Self { | ||
self.0 += 1; | ||
self.clone() | ||
} | ||
} | ||
|
||
#[derive(Default, PartialEq, Eq, Clone, Hash, Debug)] | ||
pub struct ProcID(u64); | ||
impl From<u64> for ProcID { | ||
fn from(value: u64) -> Self { | ||
Self(value) | ||
} | ||
} | ||
impl From<ProcID> for u64 { | ||
fn from(value: ProcID) -> Self { | ||
value.0 | ||
} | ||
} | ||
impl ProcID { | ||
pub fn next(&mut self) -> Self { | ||
let id = self.clone(); | ||
self.0 += 1; | ||
id | ||
} | ||
} | ||
|
||
pub struct GlobalData { | ||
tx_ctx: HashMap<TxID, TxContext>, | ||
tx_ctx_id_count: TxID, | ||
} | ||
impl Default for GlobalData { | ||
fn default() -> Self { | ||
TxContext::set_ctx_id(0.into()); | ||
Self { | ||
tx_ctx: [(0.into(), TxContext::default())].into(), | ||
tx_ctx_id_count: 1.into(), | ||
} | ||
} | ||
} | ||
|
||
impl GlobalData { | ||
pub fn get() -> &'static Mutex<Self> { | ||
if unsafe { GLOBAL_DATA_PTR.is_null() } { | ||
&GLOBAL_DATA | ||
} else { | ||
unsafe { &mut *GLOBAL_DATA_PTR as &mut Mutex<Self> } | ||
} | ||
} | ||
pub fn locked() -> MutexGuard<'static, Self> { | ||
Self::get().lock().unwrap() | ||
} | ||
pub fn get_ptr() -> *const c_void { | ||
if unsafe { GLOBAL_DATA_PTR.is_null() } { | ||
let infos_ref: &Mutex<Self> = &GLOBAL_DATA; | ||
infos_ref as *const Mutex<Self> as *const c_void | ||
} else { | ||
unsafe { GLOBAL_DATA_PTR as *const c_void } | ||
} | ||
} | ||
pub fn set_ptr(ptr: *const c_void) { | ||
unsafe { | ||
GLOBAL_DATA_PTR = ptr as *mut Mutex<GlobalData>; | ||
} | ||
} | ||
|
||
pub fn set_tx(&mut self, ctx: TxContext) -> TxID { | ||
self.tx_ctx.insert(self.tx_ctx_id_count.next(), ctx); | ||
self.tx_ctx_id_count.clone() | ||
} | ||
pub fn get_tx(&self, id: &TxID) -> &TxContext { | ||
self.tx_ctx | ||
.get(id) | ||
.unwrap_or_else(|| panic!("unknow tx context: {:?}", id)) | ||
} | ||
pub fn get_tx_mut(&mut self, id: &TxID) -> &mut TxContext { | ||
self.tx_ctx | ||
.get_mut(id) | ||
.unwrap_or_else(|| panic!("unknow mut tx context: {:?}", id)) | ||
} | ||
} | ||
|
||
#[macro_export] | ||
macro_rules! get_tx { | ||
($txid:expr) => { | ||
GlobalData::locked().get_tx(&$txid) | ||
}; | ||
} | ||
|
||
#[macro_export] | ||
macro_rules! get_tx_mut { | ||
($txid:expr) => { | ||
GlobalData::locked().get_tx_mut(&$txid) | ||
}; | ||
} | ||
|
||
#[macro_export] | ||
macro_rules! get_proc { | ||
($txid: expr, $procid: expr) => { | ||
GlobalData::locked().get_tx(&$txid).process(&$procid) | ||
}; | ||
} | ||
|
||
#[macro_export] | ||
macro_rules! get_cur_proc { | ||
() => { | ||
GlobalData::locked() | ||
.get_tx(&TxContext::ctx_id()) | ||
.process(&Process::ctx_id()) | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,15 @@ | ||
pub mod constants; | ||
|
||
pub mod spawn; | ||
pub use spawn::*; | ||
|
||
mod global_data; | ||
mod process_info; | ||
mod utils; | ||
|
||
use global_data::GlobalData; | ||
use process_info::{Process, TxContext}; | ||
|
||
#[macro_use] | ||
extern crate lazy_static; | ||
|
||
|
@@ -20,7 +30,7 @@ use constants::{ | |
}; | ||
use serde_derive::{Deserialize, Serialize}; | ||
use std::collections::HashMap; | ||
use std::ffi::{CStr, CString}; | ||
use std::ffi::CString; | ||
use std::os::raw::{c_char, c_int, c_void}; | ||
|
||
#[derive(Clone, Serialize, Deserialize)] | ||
|
@@ -56,7 +66,7 @@ lazy_static! { | |
} | ||
|
||
fn assert_vm_version() { | ||
if SETUP.vm_version != 1 { | ||
if SETUP.vm_version != 1 && SETUP.vm_version != 2 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There may be version 3 in the future, use |
||
panic!( | ||
"Currently running setup vm_version({}) not support this syscall", | ||
SETUP.vm_version | ||
|
@@ -94,45 +104,40 @@ pub extern "C" fn ckb_exec_cell( | |
) -> c_int { | ||
assert_vm_version(); | ||
|
||
let mut filename = None; | ||
for ht in [hash_type, 0xFF] { | ||
let code_hash = unsafe { std::slice::from_raw_parts(code_hash, 32) }; | ||
let mut buffer = vec![]; | ||
buffer.extend_from_slice(code_hash); | ||
buffer.push(ht); | ||
buffer.extend_from_slice(&offset.to_be_bytes()[..]); | ||
buffer.extend_from_slice(&length.to_be_bytes()[..]); | ||
let key = format!("0x{}", faster_hex::hex_string(&buffer)); | ||
filename = SETUP.native_binaries.get(&key); | ||
if filename.is_some() { | ||
break; | ||
} | ||
} | ||
let filename = filename.expect("cannot locate native binary for ckb_exec syscall!"); | ||
let sim_path = | ||
utils::get_simulator_path(utils::to_array(code_hash, 32), hash_type, offset, length); | ||
let sim_path = sim_path.expect("cannot locate native binary for ckb_exec syscall!"); | ||
|
||
match SETUP.run_type.as_ref().unwrap_or(&RunningType::Executable) { | ||
RunningType::Executable => { | ||
let filename_cstring = CString::new(filename.as_bytes().to_vec()).unwrap(); | ||
let filename_cstring = CString::new(sim_path.as_bytes().to_vec()).unwrap(); | ||
unsafe { | ||
let args = argv as *const *const i8; | ||
libc::execvp(filename_cstring.as_ptr(), args) | ||
} | ||
} | ||
RunningType::DynamicLib => { | ||
use core::ffi::c_int; | ||
type CkbMainFunc<'a> = libloading::Symbol< | ||
'a, | ||
unsafe extern "C" fn(argc: c_int, argv: *const *const i8) -> i8, | ||
>; | ||
use utils::CkbNativeSimulator; | ||
|
||
unsafe { | ||
let lib = libloading::Library::new(filename).expect("Load library"); | ||
let func: CkbMainFunc = lib | ||
.get(b"__ckb_std_main") | ||
.expect("load function : __ckb_std_main"); | ||
let args = argv as *const *const i8; | ||
std::process::exit(func(argc, args).into()) | ||
} | ||
let tx_ctx_id = GlobalData::locked().set_tx(process_info::TxContext::default()); | ||
TxContext::set_ctx_id(tx_ctx_id.clone()); | ||
|
||
let sim = CkbNativeSimulator::new_by_hash(code_hash, hash_type, offset, length); | ||
let args = utils::to_vec_args(argc, argv as *const *const i8); | ||
|
||
let t = std::thread::spawn(move || { | ||
let proc_id = get_tx_mut!(&tx_ctx_id).new_process(None, &[]); | ||
|
||
Process::set_ctx_id(proc_id.clone()); | ||
TxContext::set_ctx_id(tx_ctx_id.clone()); | ||
|
||
sim.update_script_info(tx_ctx_id.clone(), proc_id.clone()); | ||
|
||
sim.ckb_std_main(args) | ||
// get_cur_proc!().notify(); | ||
}); | ||
|
||
t.join().expect("exec dylib") as c_int | ||
} | ||
} | ||
} | ||
|
@@ -165,7 +170,7 @@ pub extern "C" fn ckb_load_script(ptr: *mut c_void, len: *mut u64, offset: u64) | |
|
||
#[no_mangle] | ||
pub extern "C" fn ckb_debug(s: *const c_char) { | ||
let message = unsafe { CStr::from_ptr(s) }.to_str().expect("UTF8 error!"); | ||
let message = utils::to_c_str(s).to_str().expect("UTF8 error!"); | ||
println!("Debug message: {}", message); | ||
} | ||
|
||
|
@@ -378,6 +383,29 @@ extern "C" { | |
) -> c_int; | ||
} | ||
|
||
// TO fix clippy error: clippy::not_unsafe_ptr_arg_deref | ||
fn rs_simulator_internal_dlopen2( | ||
native_library_path: *const u8, | ||
code: *const u8, | ||
length: u64, | ||
aligned_addr: *mut u8, | ||
aligned_size: u64, | ||
handle: *mut *mut c_void, | ||
consumed_size: *mut u64, | ||
) -> c_int { | ||
unsafe { | ||
simulator_internal_dlopen2( | ||
native_library_path, | ||
code, | ||
length, | ||
aligned_addr, | ||
aligned_size, | ||
handle, | ||
consumed_size, | ||
) | ||
} | ||
} | ||
|
||
#[no_mangle] | ||
pub extern "C" fn ckb_dlopen2( | ||
dep_cell_hash: *const u8, | ||
|
@@ -387,7 +415,7 @@ pub extern "C" fn ckb_dlopen2( | |
handle: *mut *mut c_void, | ||
consumed_size: *mut u64, | ||
) -> c_int { | ||
let dep_cell_hash = unsafe { std::slice::from_raw_parts(dep_cell_hash, 32) }; | ||
let dep_cell_hash = utils::to_array(dep_cell_hash, 32); | ||
let mut buffer = vec![]; | ||
buffer.extend_from_slice(dep_cell_hash); | ||
buffer.push(hash_type); | ||
|
@@ -414,17 +442,22 @@ pub extern "C" fn ckb_dlopen2( | |
}) | ||
.expect("cannot locate cell dep"); | ||
let cell_data = cell_dep.data.as_ref(); | ||
unsafe { | ||
simulator_internal_dlopen2( | ||
filename.as_str().as_ptr(), | ||
cell_data.as_ptr(), | ||
cell_data.len() as u64, | ||
aligned_addr, | ||
aligned_size, | ||
handle, | ||
consumed_size, | ||
) | ||
} | ||
rs_simulator_internal_dlopen2( | ||
filename.as_str().as_ptr(), | ||
cell_data.as_ptr(), | ||
cell_data.len() as u64, | ||
aligned_addr, | ||
aligned_size, | ||
handle, | ||
consumed_size, | ||
) | ||
} | ||
|
||
#[no_mangle] | ||
pub extern "C" fn set_script_info(ptr: *const std::ffi::c_void, tx_ctx_id: u64, proc_ctx_id: u64) { | ||
GlobalData::set_ptr(ptr); | ||
TxContext::set_ctx_id(tx_ctx_id.into()); | ||
Process::set_ctx_id(proc_ctx_id.into()); | ||
} | ||
|
||
fn fetch_cell(index: u64, source: u64) -> Result<(CellOutput, Bytes), c_int> { | ||
|
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you modify the original data here, but clone a copy of the data as the return value at the same time?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In many places, the
next
step isHashMap::insert
. This way, the return is more convenient to use.