blob: 2d18bb336565d78ded3c26aa36ab9ce9b0baac20 [file]
// Copyright 2017 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
use crate::kernel::deadline::Deadline;
use crate::object::{HandleValue, OwnerAction, ProcessDispatcher};
use crate::platform_rs::timer::InstantUnknown;
use crate::user_copy::{UserInPtr, UserOutPtr};
use debug::ltracef;
use syscalls_macro::syscall;
use zx_status::Status;
use zx_types::{zx_futex_t, zx_instant_mono_t, zx_koid_t};
const LOCAL_TRACE: u32 = 0;
// zx_status_t zx_futex_wait
#[syscall]
pub fn sys_futex_wait(
value_ptr: UserInPtr<zx_futex_t>,
current_value: i32,
new_futex_owner: HandleValue,
deadline: zx_instant_mono_t,
) -> Result<(), Status> {
ltracef!("futex {:p} current {}\n", value_ptr.as_ptr(), current_value);
ProcessDispatcher::with_current(|dispatcher| {
let slack = dispatcher.get_timer_slack_policy();
let slack_deadline = Deadline::new(InstantUnknown(deadline), slack);
dispatcher.futex_context().futex_wait(
value_ptr,
current_value,
new_futex_owner,
&slack_deadline,
)
})
}
// zx_status_t zx_futex_wake
#[syscall]
pub fn sys_futex_wake(value_ptr: UserInPtr<zx_futex_t>, count: u32) -> Result<(), Status> {
ltracef!("futex {:p} count {}\n", value_ptr.as_ptr(), count);
ProcessDispatcher::with_current(|up| {
up.futex_context().futex_wake(value_ptr, count, OwnerAction::Release)
})
}
// zx_status_t zx_futex_requeue
#[syscall]
pub fn sys_futex_requeue(
wake_ptr: UserInPtr<zx_futex_t>,
wake_count: u32,
current_value: i32,
requeue_ptr: UserInPtr<zx_futex_t>,
requeue_count: u32,
requeue_owner: HandleValue,
) -> Result<(), Status> {
ltracef!(
"futex {:p} wake_count {}current_value {} requeue_futex {:p} requeue_count {}\n",
wake_ptr.as_ptr(),
wake_count,
current_value,
requeue_ptr.as_ptr(),
requeue_count
);
ProcessDispatcher::with_current(|up| {
up.futex_context().futex_requeue(
wake_ptr,
wake_count,
current_value,
OwnerAction::Release,
requeue_ptr,
requeue_count,
requeue_owner,
)
})
}
// zx_status_t zx_futex_wake_single_owner
#[syscall]
pub fn sys_futex_wake_single_owner(value_ptr: UserInPtr<zx_futex_t>) -> Result<(), Status> {
ltracef!("futex {:p}\n", value_ptr.as_ptr());
ProcessDispatcher::with_current(|up| {
up.futex_context().futex_wake(value_ptr, 1, OwnerAction::AssignWoken)
})
}
// zx_status_t zx_futex_requeue_single_owner
#[syscall]
pub fn sys_futex_requeue_single_owner(
wake_ptr: UserInPtr<zx_futex_t>,
current_value: i32,
requeue_ptr: UserInPtr<zx_futex_t>,
requeue_count: u32,
requeue_owner: HandleValue,
) -> Result<(), Status> {
ltracef!(
"futex {:p} current_value {} requeue_futex {:p} requeue_count {}\n",
wake_ptr.as_ptr(),
current_value,
requeue_ptr.as_ptr(),
requeue_count
);
ProcessDispatcher::with_current(|up| {
up.futex_context().futex_requeue(
wake_ptr,
1,
current_value,
OwnerAction::AssignWoken,
requeue_ptr,
requeue_count,
requeue_owner,
)
})
}
#[syscall]
pub fn sys_futex_get_owner(
value_ptr: UserInPtr<zx_futex_t>,
koid: UserOutPtr<zx_koid_t>,
) -> Result<(), Status> {
ltracef!("futex {:p}\n", value_ptr.as_ptr());
ProcessDispatcher::with_current(|up| up.futex_context().futex_get_owner(value_ptr, koid))
}