-
Notifications
You must be signed in to change notification settings - Fork 2
/
vhandle_sync.h
73 lines (57 loc) · 2.11 KB
/
vhandle_sync.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#ifndef _VHANDLE_SYNC_H
#define _VHANDLE_SYNC_H
#include "vhandle.h"
namespace felis {
// Spinner Slots Because we're using a coroutine library, so our coroutines are
// not preemptive. When a coroutine needs to wait for some condition, it just
// spins on this per-cpu spinner slot rather than the condition.
//
// This also requires the condition notifier be able to aware of that. What we
// can do for our sorted versioning is to to store a bitmap in the magic number
// count. This limits us to *63 cores* at maximum though. Exceeding this limit
// might lead us to use share spinner slots.
struct SpinnerSlotData;
class SpinnerSlot : public VHandleSyncService {
SpinnerSlotData *buffer;
public:
SpinnerSlot();
SpinnerSlotData *slot(int idx);
void ClearWaitCountStats() final override;
long GetWaitCountStat(int core) final override;
bool Spin(uint64_t sid, uint64_t ver, ulong &wait_cnt, volatile uintptr_t *ptr);
void Notify(uint64_t bitmap);
bool IsPendingVal(uintptr_t val) {
return (val >> 32) == (kPendingValue >> 32);
}
void WaitForData(volatile uintptr_t *addr, uint64_t sid, uint64_t ver, void *handle) final override;
void OfferData(volatile uintptr_t *addr, uintptr_t obj) final override;
};
struct SimpleSyncData;
class SimpleSync : public VHandleSyncService {
SimpleSyncData *buffer;
public:
SimpleSync();
void ClearWaitCountStats() final override;
long GetWaitCountStat(int core) final override;
void WaitForData(volatile uintptr_t *addr, uint64_t sid, uint64_t ver, void *handle) final override;
void OfferData(volatile uintptr_t *addr, uintptr_t obj) final override;
bool IsPendingVal(uintptr_t val) {
return val == kPendingValue;
}
};
}
namespace util {
template <>
struct InstanceInit<felis::SpinnerSlot> {
static constexpr bool kHasInstance = true;
static inline felis::SpinnerSlot *instance;
InstanceInit() { instance = new felis::SpinnerSlot(); }
};
template <>
struct InstanceInit<felis::SimpleSync> {
static constexpr bool kHasInstance = true;
static inline felis::SimpleSync *instance;
InstanceInit() { instance = new felis::SimpleSync(); }
};
}
#endif