// Copyright 2020 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "host-common/goldfish_sync.h"
#include "host-common/GoldfishSyncCommandQueue.h"

#include "base/Lookup.h"
#include "base/ConditionVariable.h"
#include "base/Lock.h"

#include <unordered_map>

using android::base::AutoLock;
using android::base::ConditionVariable;
using android::base::Lock;
using android::base::StaticLock;
using android::GoldfishSyncCommandQueue;

// Commands can be tagged with with unique id's,
// so that for the commands that require a reply
// from the guest, we signal them properly.
static uint64_t sUniqueId = 0;
// When we track command completion, we need to be
// careful about concurrent access.
// |sCommandReplyLock| protects
// |sUniqueId| and |wait_map|, including
// the |CommandWaitInfo| structures within.
static StaticLock sCommandReplyLock = {};

uint64_t next_unique_id() {
    AutoLock lock(sCommandReplyLock);
    uint64_t res = sUniqueId;
    sUniqueId += 1;
    return res;
}

struct CommandWaitInfo {
    Lock lock; // protects other parts of this struct
    bool done = false;
    ConditionVariable cvDone;
    uint64_t return_value;
};

// |wait_map| keeps track of all the commands in flight
// that require a reply from the guest.
static std::unordered_map<uint64_t, std::unique_ptr<CommandWaitInfo> >
    wait_map;

static CommandWaitInfo* allocWait(uint64_t id) {
    AutoLock lock(sCommandReplyLock);
    std::unique_ptr<CommandWaitInfo>& res =
        wait_map[id];
    res.reset(new CommandWaitInfo);
    return res.get();
}

static void freeWait(uint64_t id) {
    AutoLock lock(sCommandReplyLock);
    wait_map.erase(id);
}

static GoldfishSyncDeviceInterface* sGoldfishSyncHwFuncs = NULL;

////////////////////////////////////////////////////////////////////////////////
// Goldfish sync device: command send/receive protocol
// To send commands to the virtual device, there are two
// alternatives:
// - |sendCommand|, which just sends the command without waiting
//   for a reply.
// - |sendCommandAndGetResult|, which sends the command and waits
//   for that command to have completed in the guest.

// |sendCommand| is used to send Goldfish sync commands while
// not caring about a reply from the guest. During normal operation,
// we will only use |sendCommand| to send over a |goldfish_sync_timeline_inc|
// call, to signal fence FD's on the guest.
static void sendCommand(uint32_t cmd,
                        uint64_t handle,
                        uint32_t time_arg) {
    GoldfishSyncCommandQueue::hostSignal
        (cmd, handle, time_arg, 0
         // last arg 0 OK because we will not reference it
        );
}

// Receiving commands can be interesting because we do not know when
// the kernel will get to servicing a command we sent from the host.
//
// |receiveCommandResult| is for host->guest goldfish sync commands
// that require a reply from the guest. So far, this is used only
// in the functional tests, as we never issue
// |goldfish_sync_create_timeline| / |goldfish_sync_create_fence|
// from the host directly in normal operation.
//
// This function will be called by the virtual device
// upon receiving a reply from the guest for the host->guest
// commands that require replies.
//
// The implementation is that such commands will use a condition
// variable that waits on the result.
void goldfish_sync_receive_hostcmd_result(uint32_t cmd,
                                          uint64_t handle,
                                          uint32_t time_arg,
                                          uint64_t hostcmd_handle) {
    if (auto elt = android::base::find(wait_map, hostcmd_handle)) {
        CommandWaitInfo* wait_info = elt->get();
        AutoLock lock(wait_info->lock);
        wait_info->return_value = handle;
        wait_info->done = true;
        wait_info->cvDone.broadcast();
    }
}

// |sendCommandAndGetResult| uses |sendCommand| and
// |goldfish_sync_receive_hostcmd_result| for processing
// commands that require replies from the guest.
static uint64_t sendCommandAndGetResult(uint64_t cmd,
                                        uint64_t handle,
                                        uint64_t time_arg,
                                        uint64_t hostcmd_handle) {

    // queue a signal to the device
    GoldfishSyncCommandQueue::hostSignal
        (cmd, handle, time_arg, hostcmd_handle);

    CommandWaitInfo* waitInfo = allocWait(hostcmd_handle);

    uint64_t res;

    {
        AutoLock lock(waitInfo->lock);
        while (!waitInfo->done) {
            waitInfo->cvDone.wait(&waitInfo->lock);
        }

        res = waitInfo->return_value;
    }

    freeWait(hostcmd_handle);

    return res;
}

// Goldfish sync host-side interface implementation/////////////////////////////

uint64_t goldfish_sync_create_timeline() {
    return sendCommandAndGetResult(CMD_CREATE_SYNC_TIMELINE,
                                   0, 0, next_unique_id());
}

int goldfish_sync_create_fence(uint64_t timeline, uint32_t pt) {
    return (int)sendCommandAndGetResult(CMD_CREATE_SYNC_FENCE,
                                        timeline, pt, next_unique_id());
}

void goldfish_sync_timeline_inc(uint64_t timeline, uint32_t howmuch) {
    sendCommand(CMD_SYNC_TIMELINE_INC, timeline, howmuch);
}

void goldfish_sync_destroy_timeline(uint64_t timeline) {
    sendCommand(CMD_DESTROY_SYNC_TIMELINE, timeline, 0);
}

void goldfish_sync_register_trigger_wait(trigger_wait_fn_t f) {
    if (goldfish_sync_device_exists()) {
        sGoldfishSyncHwFuncs->registerTriggerWait(f);
    }
}

bool goldfish_sync_device_exists() {
    // The idea here is that the virtual device should set
    // sGoldfishSyncHwFuncs. If it didn't do that, we take
    // that to mean there is no virtual device.
    return sGoldfishSyncHwFuncs != NULL;
}

void goldfish_sync_set_hw_funcs(GoldfishSyncDeviceInterface* hw_funcs) {
    sGoldfishSyncHwFuncs = hw_funcs;
    GoldfishSyncCommandQueue::setQueueCommand
        (sGoldfishSyncHwFuncs->doHostCommand);
}

