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