Skip to content

Commit

Permalink
feature(fiber): fiber name is set from caller source location
Browse files Browse the repository at this point in the history
this adds some overhead when creating fibers as now the compiler passes
an additional implicit parameter to the fiber creation functions which
also call a function for getting the location info.

However at some point in the future these functions will become `const`
which means that the overhead will disappear automatically.

The allocations required for `format` won't probably disappear as soon
though :(
  • Loading branch information
gmoshkin committed Apr 4, 2022
1 parent 9c4b374 commit 771bca4
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 1 deletion.
32 changes: 31 additions & 1 deletion tarantool/src/fiber.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,11 @@ macro_rules! inner_spawn {
($self:expr, $invocation:tt) => {
{
let Self { name, attr, f } = $self;
let name = name.unwrap_or_else(|| "<rust>".into());
let name = if let Some(name) = name {
name
} else {
impl_details::fiber_name_from_caller()
};
Ok(Fyber::$invocation(name, f, attr.as_ref())?.spawn())
}
};
Expand All @@ -355,6 +359,7 @@ where
/// to the new fiber immediately.
///
/// See the [`start`] free function for more details.
#[track_caller]
pub fn start(self) -> Result<C::JoinHandle> {
inner_spawn!(self, immediate)
}
Expand All @@ -370,6 +375,7 @@ where
/// In the future we are planning to add a correct implementation.
///
/// See the [`defer`] free function for more details.
#[track_caller]
pub fn defer(self) -> Result<C::JoinHandle> {
inner_spawn!(self, deferred)
}
Expand Down Expand Up @@ -498,8 +504,11 @@ where
Self { callee }
}

#[track_caller]
pub fn spawn(self) -> Result<C::JoinHandle> {
let Self { callee } = self;
let name = impl_details::fiber_name_from_caller();

let fiber_ref = unsafe {
let l = ffi::luaT_state();
lua::lua_getglobal(l, c_ptr!("require"));
Expand All @@ -520,6 +529,17 @@ where
impl_details::guarded_pcall(l, 2, 0)
.map_err(|e| panic!("{}", e))
.unwrap();

lua::lua_getfield(l, -1, c_ptr!("name"));
lua::lua_pushvalue(l, -2);
lua::lua_pushlstring(l, name.as_ptr() as _, name.len());
impl_details::guarded_pcall(l, 2, 0)
.map_err(|e| {
// Pop the fiber module and fiber instance from the stack
lua::lua_pop(l, 2);
e
})?;

let fiber_ref = lua::luaL_ref(l, lua::LUA_REGISTRYINDEX);
// pop the fiber module from the stack
lua::lua_pop(l, 1);
Expand Down Expand Up @@ -752,6 +772,12 @@ mod impl_details {
0
}
}

#[track_caller]
pub(super) fn fiber_name_from_caller() -> String {
let loc = std::panic::Location::caller();
format!("<rust:{}:{}:{}>", loc.file(), loc.line(), loc.column())
}
}

////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -1170,6 +1196,7 @@ impl TrampolineArgs for VaList {
/// This will create a fiber using default parameters of [`Builder`], if you
/// want to specify the stack size or the name of the thread, use this API
/// instead.
#[track_caller]
pub fn start<'f, F, T>(f: F) -> JoinHandle<'f, T>
where
F: FnOnce() -> T,
Expand All @@ -1188,6 +1215,7 @@ where
/// should always be used instead of the latter.
///
/// For more details see: [`start`]
#[track_caller]
pub fn start_proc<'f, F>(f: F) -> UnitJoinHandle<'f>
where
F: FnOnce(),
Expand All @@ -1207,6 +1235,7 @@ where
///
/// The new fiber can be joined by calling [`LuaJoinHandle::join`] method on
/// it's join handle.
#[track_caller]
pub fn defer<'f, F, T>(f: F) -> LuaJoinHandle<'f, T>
where
F: FnOnce() -> T,
Expand All @@ -1226,6 +1255,7 @@ where
/// it's join handle.
///
/// This is an optimized version [`defer`]`<F, ()>`.
#[track_caller]
pub fn defer_proc<'f, F>(f: F) -> LuaUnitJoinHandle<'f>
where
F: FnOnce(),
Expand Down
23 changes: 23 additions & 0 deletions tests/src/fiber/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -468,3 +468,26 @@ pub fn lifetime() {
// }.join();
}

fn fiber_name() -> String {
let lua = tarantool::lua_state();
lua.eval("return require 'fiber'.name()").unwrap()
}

pub fn name() {
let name = fiber::start(fiber_name).join();
assert_eq!(name, format!("<rust:{}:{}:{}>", file!(), line!() - 1, 16));

let (tx, rx) = Rc::new(Cell::new(None)).into_clones();
fiber::start_proc(|| tx.set(Some(fiber_name()))).join();
let expected = format!("<rust:{}:{}:{}>", file!(), line!() - 1, 5);
assert_eq!(rx.take().unwrap(), expected);

let name = fiber::defer(fiber_name).join();
assert_eq!(name, format!("<rust:{}:{}:{}>", file!(), line!() - 1, 16));

let (tx, rx) = Rc::new(Cell::new(None)).into_clones();
fiber::defer_proc(|| tx.set(Some(fiber_name()))).join();
let expected = format!("<rust:{}:{}:{}>", file!(), line!() - 1, 5);
assert_eq!(rx.take().unwrap(), expected);
}

1 change: 1 addition & 0 deletions tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,7 @@ fn run_tests(cfg: TestConfig) -> Result<bool, io::Error> {
fiber::deferred_with_cond,
fiber::lua_thread,
fiber::lifetime,
fiber::name,

fiber::channel::send_self,
fiber::channel::send_full,
Expand Down

0 comments on commit 771bca4

Please sign in to comment.