1 /*---------------------------------------------------------------------------*
2 Project: Horizon
3 File: os_Synchronization.cpp
4
5 Copyright (C)2009 Nintendo Co., Ltd. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Rev: 12449 $
14 *---------------------------------------------------------------------------*/
15
16 #include <nn/os/os_Synchronization.h>
17 #include <nn/os/os_Result.h>
18 #include <nn/assert.h>
19 #include <nn/Handle.h>
20 #include <nn/svc/svc_Stub.h>
21 #include <nn/util/util_StaticAssert.h>
22 //---------------------------------------------------------------------------
23
24 using namespace nn;
25 //using namespace nn::svc;
26
27 namespace nn{ namespace os{
28
29 // TODO: ARM に移す必要あり
30 namespace {
31
32 struct WaitMultipleObjectsArgs {
33 s32* pOut;
34 WaitObject** objs;
35 s32 numHandles;
36 bool waitAll;
37 u8 padding[3];
38 s64* timeout;
39 };
40
WaitMultipleImpl(WaitMultipleObjectsArgs * args,nn::Handle * handles)41 nn::Result WaitMultipleImpl(WaitMultipleObjectsArgs* args, nn::Handle* handles)
42 {
43 for (int i = 0; i < args->numHandles; ++i)
44 {
45 handles[i] = args->objs[i]->GetHandle();
46 }
47 return nn::svc::WaitSynchronization(args->pOut, handles, args->numHandles, args->waitAll, *args->timeout);
48 }
49
50 NN_STATIC_ASSERT(sizeof(nn::Handle) == 4);
WaitMultipleImplWithAlloca(WaitMultipleObjectsArgs *,s32,nn::Result (*)(WaitMultipleObjectsArgs *,nn::Handle *))51 asm nn::Result WaitMultipleImplWithAlloca(WaitMultipleObjectsArgs*, s32, nn::Result (*)(WaitMultipleObjectsArgs*, nn::Handle*))
52 {
53 ARM
54 PRESERVE8
55
56 push {lr}
57
58 bics r3, r1, #1
59 addne r1, r1, #1 // r1 が奇数なら 1 を足す(8byte align のため)
60
61 mov r3, r1, LSL #2
62
63 sub sp, sp, r3
64 mov r1, sp
65
66 push {r3}
67
68 blx r2
69
70 pop {r3}
71 add sp, sp, r3
72
73 pop {pc}
74 }
75
76 }
77
WaitMultiple(s32 * pOut,WaitObject * objs[],s32 numHandles,bool waitAll,s64 timeout)78 nn::Result WaitObject::WaitMultiple(s32* pOut, WaitObject* objs[], s32 numHandles, bool waitAll, s64 timeout)
79 {
80 // TORIAEZU: 10個くらいあれば普通は十分だろう。
81 const s32 STATIC_ALLOCATE_SIZE = 10;
82 if (numHandles <= STATIC_ALLOCATE_SIZE)
83 {
84 nn::Handle handles[STATIC_ALLOCATE_SIZE];
85 for (int i = 0; i < numHandles; ++i)
86 {
87 handles[i] = objs[i]->GetHandle();
88 }
89 return nn::svc::WaitSynchronization(pOut, handles, numHandles, waitAll, timeout);
90 }
91 else
92 {
93 WaitMultipleObjectsArgs args;
94 args.pOut = pOut;
95 args.objs = objs;
96 args.numHandles = numHandles;
97 args.waitAll = waitAll;
98 args.timeout = &timeout;
99 return WaitMultipleImplWithAlloca(&args, numHandles, &WaitMultipleImpl);
100 }
101 }
102
103 }} // namespace nn::os
104
105
106 using namespace nn::os;
107
108 extern "C" {
109
nnosWaitObjectWaitOne(nnosWaitObject * p,s64 nanoSecondsTimeout)110 bool nnosWaitObjectWaitOne(nnosWaitObject* p, s64 nanoSecondsTimeout)
111 {
112 WaitObject* pWaitObject = reinterpret_cast<WaitObject*>(p);
113 return pWaitObject->WaitOne(nn::fnd::TimeSpan::FromNanoSeconds(nanoSecondsTimeout));
114 }
115
nnosWaitObjectWaitAll(nnosWaitObject * objs[],s32 numObjects,s64 nanoSecondsTimeout)116 bool nnosWaitObjectWaitAll(nnosWaitObject* objs[], s32 numObjects, s64 nanoSecondsTimeout)
117 {
118 WaitObject** pWaitObjects = reinterpret_cast<WaitObject**>(objs);
119 return WaitObject::WaitAll(pWaitObjects, numObjects, nn::fnd::TimeSpan::FromNanoSeconds(nanoSecondsTimeout));
120 }
121
nnosWaitObjectWaitAny(nnosWaitObject * objs[],s32 numObjects,s64 nanoSecondsTimeout)122 s32 nnosWaitObjectWaitAny(nnosWaitObject* objs[], s32 numObjects, s64 nanoSecondsTimeout)
123 {
124 WaitObject** pWaitObjects = reinterpret_cast<WaitObject**>(objs);
125 return WaitObject::WaitAny(pWaitObjects, numObjects, nn::fnd::TimeSpan::FromNanoSeconds(nanoSecondsTimeout));
126 }
127
128 }
129