// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <io-scheduler/worker.h>

#include <stdio.h>

#include <zircon/syscalls.h>
#include <zircon/types.h>

#include <io-scheduler/io-scheduler.h>

namespace ioscheduler {

zx_status_t Worker::Create(Scheduler* sched, uint32_t id, fbl::unique_ptr<Worker>* out) {
    fbl::AllocChecker ac;
    fbl::unique_ptr<Worker> worker(new (&ac) Worker(sched, id));
    if (!ac.check()) {
        fprintf(stderr, "Failed to allocate worker.\n");
        return ZX_ERR_NO_MEMORY;
    }
    if (thrd_create(&worker->thread_, worker->ThreadEntry, worker.get()) != ZX_OK) {
        fprintf(stderr, "Failed to create worker thread.\n");
        return ZX_ERR_NO_MEMORY;
    }
    worker->thread_started_ = true;
    *out = std::move(worker);
    return ZX_OK;
}

Worker::Worker(Scheduler* sched, uint32_t id) : sched_(sched), id_(id) { }

Worker::~Worker() {
    if (thread_started_) {
        thrd_join(thread_, nullptr);
    }
}

int Worker::ThreadEntry(void* arg) {
    Worker* w = static_cast<Worker*>(arg);
    w->WorkerLoop();
    return 0;
}

void Worker::WorkerLoop() {
    const size_t max_ops = 10;
    SchedulerClient* client = sched_->client();
    zx_status_t status;
    for ( ; ; ) {
        size_t actual_count = 0;
        SchedulerOp* op_list[max_ops];
        status = client->Acquire(op_list, max_ops, &actual_count, true);
        if (status == ZX_ERR_CANCELED) {
            // Cancel received, no more ops to read. Drain the streams and exit.
            break;
        }
        if (status != ZX_OK) {
            fprintf(stderr, "Unexpected return status from Acquire() %d\n", status);
            client->Fatal();
            break;
        }
        // Dummy issue loop. In the future, ops will be added to the scheduler.
        for (size_t i = 0; i < actual_count; i++) {
            status = client->Issue(op_list[i]);
            ZX_DEBUG_ASSERT(status == ZX_OK);   // Require synchronous completion, for now.
            client->Release(op_list[i]);
        }
    }
}

} // namespace ioscheduler
