1 /* -*- C++ -*- */
2 
3 #ifndef HL_PHOTHREADHEAP_H
4 #define HL_PHOTHREADHEAP_H
5 
6 #include <assert.h>
7 
8 #include "threads/cpuinfo.h"
9 
10 #if defined(__clang__)
11 #pragma clang diagnostic push
12 #pragma clang diagnostic ignored "-Wunused-variable"
13 #endif
14 
15 using namespace HL;
16 
17 template <int NumHeaps, class SuperHeap>
18 class MarkThreadHeap : public SuperHeap {
19 public:
20 
malloc(size_t sz)21   inline void * malloc (size_t sz) {
22     int tid = CPUInfo::getThreadId() % NumHeaps;
23     void * ptr = SuperHeap::malloc (sz);
24     if (ptr != NULL) {
25       SuperHeap::setHeap(ptr, tid);
26       SuperHeap::setPrevHeap(SuperHeap::getNext(ptr), tid);
27     }
28     return ptr;
29   }
30 };
31 
32 
33 template <int NumHeaps, class SuperHeap>
34 class CheckThreadHeap : public SuperHeap {
35 public:
36 
malloc(size_t sz)37   inline void * malloc (size_t sz) {
38     void * ptr = SuperHeap::malloc (sz);
39 #ifndef NDEBUG
40     if (ptr != NULL) {
41       int tid = CPUInfo::getThreadId() % NumHeaps;
42       assert (SuperHeap::getHeap(ptr) == tid);
43     }
44 #endif
45     return ptr;
46   }
47 
free(void * ptr)48   inline void free (void * ptr) {
49     SuperHeap::free (ptr);
50   }
51 };
52 
53 
54 
55 /*
56 
57 A PHOThreadHeap comprises NumHeaps "per-thread" heaps.
58 
59 To pick a per-thread heap, the current thread id is hashed (mod NumHeaps).
60 
61 malloc gets memory from its hashed per-thread heap.
62 free returns memory to its originating heap.
63 
64 NB: We assume that the thread heaps are 'locked' as needed.  */
65 
66 
67 template <int NumHeaps, class SuperHeap>
68 class PHOThreadHeap { // : public MarkThreadHeap<NumHeaps, SuperHeap> {
69 public:
70 
malloc(size_t sz)71   inline void * malloc (size_t sz) {
72     int tid = CPUInfo::getThreadId() % NumHeaps;
73     void * ptr = selectHeap(tid)->malloc (sz);
74     return ptr;
75   }
76 
free(void * ptr)77   inline void free (void * ptr) {
78     int tid = SuperHeap::getHeap(ptr);
79     selectHeap(tid)->free (ptr);
80   }
81 
82 
83   inline int remove (void * ptr);
84 #if 0
85   {
86     int tid = SuperHeap::getHeap(ptr);
87     selectHeap(tid)->remove (ptr);
88   }
89 #endif
90 
91 private:
92 
93   // Access the given heap within the buffer.
selectHeap(int index)94   MarkThreadHeap<NumHeaps, SuperHeap> * selectHeap (int index) {
95     assert (index >= 0);
96     assert (index < NumHeaps);
97     return &ptHeaps[index];
98   }
99 
100   MarkThreadHeap<NumHeaps, SuperHeap> ptHeaps[NumHeaps];
101 
102 };
103 
104 #if defined(__clang__)
105 #pragma clang diagnostic pop
106 #endif
107 
108 #endif
109