101 lines
2.3 KiB
C++
101 lines
2.3 KiB
C++
// 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 <cstddef>
|
|
#include <functional>
|
|
#include <queue>
|
|
#include <stack>
|
|
|
|
namespace System {
|
|
|
|
struct NativeContextGroup;
|
|
|
|
struct NativeContext {
|
|
void* ucontext;
|
|
void* stackPtr;
|
|
bool interrupted;
|
|
NativeContext* next;
|
|
NativeContextGroup* group;
|
|
NativeContext* groupPrev;
|
|
NativeContext* groupNext;
|
|
std::function<void()> procedure;
|
|
std::function<void()> interruptProcedure;
|
|
};
|
|
|
|
struct NativeContextGroup {
|
|
NativeContext* firstContext;
|
|
NativeContext* lastContext;
|
|
NativeContext* firstWaiter;
|
|
NativeContext* lastWaiter;
|
|
};
|
|
|
|
struct OperationContext {
|
|
NativeContext *context;
|
|
bool interrupted;
|
|
uint32_t events;
|
|
};
|
|
|
|
struct ContextPair {
|
|
OperationContext *readContext;
|
|
OperationContext *writeContext;
|
|
};
|
|
|
|
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<void()>&& procedure);
|
|
void yield();
|
|
|
|
// system-dependent
|
|
int getEpoll() const;
|
|
NativeContext& getReusableContext();
|
|
void pushReusableContext(NativeContext&);
|
|
int getTimer();
|
|
void pushTimer(int timer);
|
|
|
|
#ifdef __x86_64__
|
|
# if __WORDSIZE == 64
|
|
static const int SIZEOF_PTHREAD_MUTEX_T = 40;
|
|
# else
|
|
static const int SIZEOF_PTHREAD_MUTEX_T = 32;
|
|
# endif
|
|
#else
|
|
static const int SIZEOF_PTHREAD_MUTEX_T = 24;
|
|
#endif
|
|
|
|
private:
|
|
void spawn(std::function<void()>&& procedure);
|
|
int epoll;
|
|
alignas(void*) uint8_t mutex[SIZEOF_PTHREAD_MUTEX_T];
|
|
int remoteSpawnEvent;
|
|
ContextPair remoteSpawnEventContext;
|
|
std::queue<std::function<void()>> remoteSpawningProcedures;
|
|
std::stack<int> timers;
|
|
|
|
NativeContext mainContext;
|
|
NativeContextGroup contextGroup;
|
|
NativeContext* currentContext;
|
|
NativeContext* firstResumingContext;
|
|
NativeContext* lastResumingContext;
|
|
NativeContext* firstReusableContext;
|
|
size_t runningContextCount;
|
|
|
|
void contextProcedure(void* ucontext);
|
|
static void contextProcedureStatic(void* context);
|
|
};
|
|
|
|
}
|