// Copyright (c) 2011-2016 The Cryptonote developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #pragma once #include #include #include #include #include namespace System { struct NativeContextGroup; struct NativeContext { void* uctx; void* stackPtr; bool interrupted; NativeContext* next; NativeContextGroup* group; NativeContext* groupPrev; NativeContext* groupNext; std::function procedure; std::function interruptProcedure; }; struct NativeContextGroup { NativeContext* firstContext; NativeContext* lastContext; NativeContext* firstWaiter; NativeContext* lastWaiter; }; struct OperationContext { NativeContext* context; bool interrupted; }; class Dispatcher { public: Dispatcher(); Dispatcher(const Dispatcher&) = delete; ~Dispatcher(); Dispatcher& operator=(const Dispatcher&) = delete; void clear(); void dispatch(); NativeContext* getCurrentContext() const; void interrupt(); void interrupt(NativeContext* context); bool interrupted(); void pushContext(NativeContext* context); void remoteSpawn(std::function&& procedure); void yield(); int getKqueue() const; NativeContext& getReusableContext(); void pushReusableContext(NativeContext&); int getTimer(); void pushTimer(int timer); #ifdef __LP64__ static const int SIZEOF_PTHREAD_MUTEX_T = 56 + sizeof(long); #else static const int SIZEOF_PTHREAD_MUTEX_T = 40 + sizeof(long); #endif private: void spawn(std::function&& procedure); int kqueue; int lastCreatedTimer; alignas(std::max_align_t) uint8_t mutex[SIZEOF_PTHREAD_MUTEX_T]; std::atomic remoteSpawned; std::queue> remoteSpawningProcedures; std::stack timers; NativeContext mainContext; NativeContextGroup contextGroup; NativeContext* currentContext; NativeContext* firstResumingContext; NativeContext* lastResumingContext; NativeContext* firstReusableContext; size_t runningContextCount; void contextProcedure(void* uctx); static void contextProcedureStatic(intptr_t context); }; }