1 // Copyright 2017 The Fuchsia Authors
2 //
3 // Use of this source code is governed by a MIT-style
4 // license that can be found in the LICENSE file or at
5 // https://opensource.org/licenses/MIT
6
7 #include <inttypes.h>
8
9 #include <trace.h>
10
11 #include <object/process_dispatcher.h>
12 #include <zircon/types.h>
13
14 #include "priv.h"
15
16 #define LOCAL_TRACE 0
17
18 // zx_status_t zx_futex_wait
sys_futex_wait(user_in_ptr<const zx_futex_t> value_ptr,zx_futex_t current_value,zx_handle_t current_futex_owner,zx_time_t deadline)19 zx_status_t sys_futex_wait(user_in_ptr<const zx_futex_t> value_ptr, zx_futex_t current_value,
20 zx_handle_t current_futex_owner, zx_time_t deadline) {
21 LTRACEF("futex %p current %d\n", value_ptr.get(), current_value);
22
23 ProcessDispatcher* dispatcher = ThreadDispatcher::GetCurrent()->process();
24 const TimerSlack slack = dispatcher->GetTimerSlackPolicy();
25 return dispatcher->futex_context()->FutexWait(value_ptr, current_value, current_futex_owner,
26 deadline, slack);
27 }
28
29 // zx_status_t zx_futex_wake
sys_futex_wake(user_in_ptr<const zx_futex_t> value_ptr,uint32_t count)30 zx_status_t sys_futex_wake(user_in_ptr<const zx_futex_t> value_ptr, uint32_t count) {
31 LTRACEF("futex %p count %" PRIu32 "\n", value_ptr.get(), count);
32
33 return ProcessDispatcher::GetCurrent()->futex_context()->FutexWake(
34 value_ptr, count, FutexContext::OwnerAction::RELEASE);
35 }
36
37 // zx_status_t zx_futex_requeue
sys_futex_requeue(user_in_ptr<const zx_futex_t> wake_ptr,uint32_t wake_count,zx_futex_t current_value,user_in_ptr<const zx_futex_t> requeue_ptr,uint32_t requeue_count,zx_handle_t requeue_owner)38 zx_status_t sys_futex_requeue(user_in_ptr<const zx_futex_t> wake_ptr,
39 uint32_t wake_count,
40 zx_futex_t current_value,
41 user_in_ptr<const zx_futex_t> requeue_ptr,
42 uint32_t requeue_count,
43 zx_handle_t requeue_owner) {
44 LTRACEF("futex %p wake_count %" PRIu32 "current_value %d "
45 "requeue_futex %p requeue_count %" PRIu32 "\n",
46 wake_ptr.get(), wake_count, current_value, requeue_ptr.get(), requeue_count);
47
48 return ProcessDispatcher::GetCurrent()->futex_context()->FutexRequeue(
49 wake_ptr, wake_count, current_value, FutexContext::OwnerAction::RELEASE,
50 requeue_ptr, requeue_count, requeue_owner);
51 }
52
53 // zx_status_t zx_futex_wake_single_owner
sys_futex_wake_single_owner(user_in_ptr<const zx_futex_t> value_ptr)54 zx_status_t sys_futex_wake_single_owner(user_in_ptr<const zx_futex_t> value_ptr) {
55 LTRACEF("futex %p\n", value_ptr.get());
56
57 return ProcessDispatcher::GetCurrent()->futex_context()->FutexWake(
58 value_ptr, 1u, FutexContext::OwnerAction::ASSIGN_WOKEN);
59 }
60
61 // zx_status_t zx_futex_requeue_single_owner
sys_futex_requeue_single_owner(user_in_ptr<const zx_futex_t> wake_ptr,zx_futex_t current_value,user_in_ptr<const zx_futex_t> requeue_ptr,uint32_t requeue_count,zx_handle_t requeue_owner)62 zx_status_t sys_futex_requeue_single_owner(user_in_ptr<const zx_futex_t> wake_ptr,
63 zx_futex_t current_value,
64 user_in_ptr<const zx_futex_t> requeue_ptr,
65 uint32_t requeue_count,
66 zx_handle_t requeue_owner) {
67 LTRACEF("futex %p current_value %d requeue_futex %p requeue_count %" PRIu32 "\n",
68 wake_ptr.get(), current_value, requeue_ptr.get(), requeue_count);
69
70 return ProcessDispatcher::GetCurrent()->futex_context()->FutexRequeue(
71 wake_ptr, 1u, current_value, FutexContext::OwnerAction::ASSIGN_WOKEN,
72 requeue_ptr, requeue_count, requeue_owner);
73 }
74
sys_futex_get_owner(user_in_ptr<const zx_futex_t> value_ptr,user_out_ptr<zx_koid_t> koid)75 zx_status_t sys_futex_get_owner(user_in_ptr<const zx_futex_t> value_ptr,
76 user_out_ptr<zx_koid_t> koid) {
77 LTRACEF("futex %p\n", value_ptr.get());
78 return ProcessDispatcher::GetCurrent()->futex_context()->FutexGetOwner(value_ptr, koid);
79 }
80
81 // zx_status_t zx_futex_wait_deprecated
sys_futex_wait_deprecated(user_in_ptr<const zx_futex_t> value_ptr,int32_t current_value,zx_time_t deadline)82 zx_status_t sys_futex_wait_deprecated(
83 user_in_ptr<const zx_futex_t> value_ptr, int32_t current_value, zx_time_t deadline) {
84 return sys_futex_wait(value_ptr, current_value, ZX_HANDLE_INVALID, deadline);
85 }
86
87 // zx_status_t zx_futex_requeue_deprecated
sys_futex_requeue_deprecated(user_in_ptr<const zx_futex_t> wake_ptr,uint32_t wake_count,int32_t current_value,user_in_ptr<const zx_futex_t> requeue_ptr,uint32_t requeue_count)88 zx_status_t sys_futex_requeue_deprecated(
89 user_in_ptr<const zx_futex_t> wake_ptr, uint32_t wake_count, int32_t current_value,
90 user_in_ptr<const zx_futex_t> requeue_ptr, uint32_t requeue_count) {
91 return sys_futex_requeue(wake_ptr, wake_count, current_value,
92 requeue_ptr, requeue_count, ZX_HANDLE_INVALID);
93 }
94