2016-01-18 15:33:29 +00:00
|
|
|
// Copyright (c) 2011-2016 The Cryptonote developers
|
2015-04-23 16:07:22 +00:00
|
|
|
// Distributed under the MIT/X11 software license, see the accompanying
|
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
2014-09-15 10:48:45 +00:00
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
#include <cstdint>
|
2014-09-15 10:48:45 +00:00
|
|
|
#include <functional>
|
2015-05-27 12:08:46 +00:00
|
|
|
#include <map>
|
2014-09-15 10:48:45 +00:00
|
|
|
#include <queue>
|
|
|
|
|
2015-04-06 16:13:07 +00:00
|
|
|
namespace System {
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
struct NativeContextGroup;
|
|
|
|
|
|
|
|
struct NativeContext {
|
|
|
|
void* fiber;
|
|
|
|
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;
|
|
|
|
};
|
|
|
|
|
2015-04-06 16:13:07 +00:00
|
|
|
class Dispatcher {
|
2014-09-15 10:48:45 +00:00
|
|
|
public:
|
2015-04-06 16:13:07 +00:00
|
|
|
Dispatcher();
|
|
|
|
Dispatcher(const Dispatcher&) = delete;
|
|
|
|
~Dispatcher();
|
|
|
|
Dispatcher& operator=(const Dispatcher&) = delete;
|
|
|
|
void clear();
|
2015-05-27 12:08:46 +00:00
|
|
|
void dispatch();
|
2015-07-30 15:22:07 +00:00
|
|
|
NativeContext* getCurrentContext() const;
|
|
|
|
void interrupt();
|
|
|
|
void interrupt(NativeContext* context);
|
|
|
|
bool interrupted();
|
|
|
|
void pushContext(NativeContext* context);
|
2015-05-27 12:08:46 +00:00
|
|
|
void remoteSpawn(std::function<void()>&& procedure);
|
2014-09-15 10:48:45 +00:00
|
|
|
void yield();
|
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
// Platform-specific
|
2015-07-30 15:22:07 +00:00
|
|
|
void addTimer(uint64_t time, NativeContext* context);
|
2015-05-27 12:08:46 +00:00
|
|
|
void* getCompletionPort() const;
|
2015-07-30 15:22:07 +00:00
|
|
|
NativeContext& getReusableContext();
|
|
|
|
void pushReusableContext(NativeContext&);
|
|
|
|
void interruptTimer(uint64_t time, NativeContext* context);
|
2015-04-06 16:13:07 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
private:
|
2015-07-30 15:22:07 +00:00
|
|
|
void spawn(std::function<void()>&& procedure);
|
2015-04-06 16:13:07 +00:00
|
|
|
void* completionPort;
|
2015-05-27 12:08:46 +00:00
|
|
|
uint8_t criticalSection[2 * sizeof(long) + 4 * sizeof(void*)];
|
|
|
|
bool remoteNotificationSent;
|
|
|
|
std::queue<std::function<void()>> remoteSpawningProcedures;
|
|
|
|
uint8_t remoteSpawnOverlapped[4 * sizeof(void*)];
|
|
|
|
uint32_t threadId;
|
2015-07-30 15:22:07 +00:00
|
|
|
std::multimap<uint64_t, NativeContext*> timers;
|
2015-04-06 16:13:07 +00:00
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
NativeContext mainContext;
|
|
|
|
NativeContextGroup contextGroup;
|
|
|
|
NativeContext* currentContext;
|
|
|
|
NativeContext* firstResumingContext;
|
|
|
|
NativeContext* lastResumingContext;
|
|
|
|
NativeContext* firstReusableContext;
|
|
|
|
size_t runningContextCount;
|
2015-04-06 16:13:07 +00:00
|
|
|
|
|
|
|
void contextProcedure();
|
|
|
|
static void __stdcall contextProcedureStatic(void* context);
|
2014-09-15 10:48:45 +00:00
|
|
|
};
|
2015-04-06 16:13:07 +00:00
|
|
|
|
|
|
|
}
|