1 // Copyright 2020 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "GoldfishSyncCommandQueue.h"
16
17 #include <memory>
18 #include <string>
19 #include <vector>
20
21 namespace android {
22
23 using base::Stream;
24
sCommandQueue()25 static GoldfishSyncCommandQueue* sCommandQueue() {
26 static GoldfishSyncCommandQueue* s = new GoldfishSyncCommandQueue;
27 return s;
28 }
29
30 // static
initThreading(VmLock * vmLock)31 void GoldfishSyncCommandQueue::initThreading(VmLock* vmLock) {
32 // TODO: trivial timer implementation for now.
33 sCommandQueue()->init(vmLock, {
34 [](DeviceContextRunner<GoldfishSyncWakeInfo>* dcr, std::function<void()> installedCallback) {
35 (void)dcr;
36 (void)installedCallback;
37 },
38 [](DeviceContextRunner<GoldfishSyncWakeInfo>* dcr) {
39 (void)dcr;
40 },
41 [](DeviceContextRunner<GoldfishSyncWakeInfo>* dcr, uint64_t timeout) {
42 (void)dcr;
43 (void)timeout;
44 },
45 });
46 }
47
48 // static
setQueueCommand(queue_device_command_t fx)49 void GoldfishSyncCommandQueue::setQueueCommand(queue_device_command_t fx) {
50 GoldfishSyncCommandQueue* cmdQueue = sCommandQueue();
51 cmdQueue->tellSyncDevice = fx;
52 }
53
54 // static
hostSignal(uint32_t cmd,uint64_t handle,uint32_t time_arg,uint64_t hostcmd_handle)55 void GoldfishSyncCommandQueue::hostSignal(uint32_t cmd,
56 uint64_t handle,
57 uint32_t time_arg,
58 uint64_t hostcmd_handle) {
59
60 GoldfishSyncCommandQueue* queue = sCommandQueue();
61
62 GoldfishSyncWakeInfo sync_data;
63 sync_data.cmd = cmd;
64 sync_data.handle = handle;
65 sync_data.time_arg = time_arg;
66 sync_data.hostcmd_handle = hostcmd_handle;
67
68 queue->queueDeviceOperation(sync_data);
69 }
70
71 // static
save(Stream * stream)72 void GoldfishSyncCommandQueue::save(Stream* stream) {
73 GoldfishSyncCommandQueue* queue = sCommandQueue();
74 stream->putBe32(queue->numPending());
75 queue->forEachPendingOperation([stream](const GoldfishSyncWakeInfo& wakeInfo) {
76 stream->putBe64(wakeInfo.handle);
77 stream->putBe64(wakeInfo.hostcmd_handle);
78 stream->putBe32(wakeInfo.cmd);
79 stream->putBe32(wakeInfo.time_arg);
80 });
81 }
82
83 // static
load(Stream * stream)84 void GoldfishSyncCommandQueue::load(Stream* stream) {
85 GoldfishSyncCommandQueue* queue = sCommandQueue();
86 queue->removeAllPendingOperations(
87 [](const GoldfishSyncWakeInfo&) { return true; });
88 uint32_t pending = stream->getBe32();
89 for (uint32_t i = 0; i < pending; i++) {
90 GoldfishSyncWakeInfo cmd = {
91 stream->getBe64(), // handle
92 stream->getBe64(), // hostcmd_handle
93 stream->getBe32(), // cmd
94 stream->getBe32(), // time_arg
95 };
96 queue->queueDeviceOperation(cmd);
97 }
98 }
99
performDeviceOperation(const GoldfishSyncWakeInfo & wakeInfo)100 void GoldfishSyncCommandQueue::performDeviceOperation
101 (const GoldfishSyncWakeInfo& wakeInfo) {
102 tellSyncDevice(wakeInfo.cmd,
103 wakeInfo.handle,
104 wakeInfo.time_arg,
105 wakeInfo.hostcmd_handle);
106 }
107
108 } // namespace android
109