Skip to content

File Thread.h

File List > Amplitude > Core > Thread.h

Go to the documentation of this file

// Copyright (c) 2021-present Sparky Studios. All rights reserved.
//
// 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.

#pragma once

#ifndef _AM_CORE_THREAD_H
#define _AM_CORE_THREAD_H

#include <condition_variable>

#include <SparkyStudios/Audio/Amplitude/Core/Common.h>

namespace SparkyStudios::Audio::Amplitude
{
    typedef void (*AmThreadFunction)(AmVoidPtr param);

    typedef AmVoidPtr AmThreadHandle;
    typedef AmUInt64 AmThreadID;

    namespace Thread
    {
        AM_API_PUBLIC AmThreadHandle CreateThread(AmThreadFunction threadFunction, AmVoidPtr parameter = nullptr);

        AM_API_PUBLIC void Sleep(AmInt32 milliseconds);

        AM_API_PUBLIC void Wait(AmThreadHandle& thread);

        AM_API_PUBLIC void Release(AmThreadHandle& thread);

        AM_API_PUBLIC AmUInt64 GetTimeMillis();

        AM_API_PUBLIC AmThreadID GetCurrentThreadId();

        AM_API_PUBLIC AmUInt32 GetCPUCount();

        class AM_API_PUBLIC PoolTask
        {
        public:
            virtual ~PoolTask() = default;

            virtual void Work() = 0;

            virtual bool Ready();
        };

        class AM_API_PUBLIC AwaitablePoolTask : public PoolTask
        {
        public:
            AwaitablePoolTask();

            ~AwaitablePoolTask() override = default;

            void Work() final;

            virtual void AwaitableWork() = 0;

            void Await();

            bool Await(AmUInt64 duration);

        private:
            std::condition_variable _condition;
            std::mutex _mutex;
        };

        class AM_API_PUBLIC Pool
        {
        public:
            Pool();

            ~Pool();

            void Init(AmUInt32 threadCount);

            void AddTask(std::shared_ptr<PoolTask> task);

            std::shared_ptr<PoolTask> GetWork();

            [[nodiscard]] AmUInt32 GetThreadCount() const;

            [[nodiscard]] bool IsRunning() const;

            [[nodiscard]] bool HasTasks() const;

            [[nodiscard]] AmInt32 GetTaskCount() const;

        private:
            AmUInt32 _threadCount; // number of threads
            AmThreadHandle* _thread; // array of thread handles
            std::mutex _workMutex; // mutex to protect task array/max task
            std::shared_ptr<PoolTask> _taskArray[AM_MAX_THREAD_POOL_TASKS]{}; // pointers to tasks
            AmInt32 _taskCount; // number of pending tasks
            AmInt32 _robin; // cyclic counter, used to pick jobs for threads
            volatile bool _running; // running flag, used to flag threads to Stop
        };
    } // namespace Thread
} // namespace SparkyStudios::Audio::Amplitude

#endif // _AM_CORE_THREAD_H