Charades
pending_heap.h
1 /**********************************************************************
2  * Additional Contributions and Acknowledgements
3  * Kalyan Perumalla - Ga Tech
4  *
5  * This implementation is an adaption of the implementation done
6  * by Kalyan for Ga Tech Time Warp
7  **********************************************************************/
8 
9 #ifndef _PENDING_HEAP_
10 #define _PENDING_HEAP_
11 
12 #include "pending_queue.h"
13 
14 #include "event.h"
15 #include "typedefs.h"
16 #include "util.h"
17 
18 #include <float.h>
19 
20 #define HEAP_INCREMENT 128
21 
22 #define LEFT(i) (2*i+1)
23 #define RIGHT(i) (2*i+2)
24 #define PARENT(i) (((i-1)/2))
25 
26 #define SWAP(x,y,t) { \
27  t = elems[x]; \
28  elems[x] = elems[y]; \
29  elems[y] = t; \
30  elems[x]->index = x; \
31  elems[y]->index = y; \
32 }
33 
34 class PendingHeap : public PendingQueue {
35  private:
36  CustomEventComparator comparator;
37  size_t nelems;
38  size_t curr_max;
39  Event** elems;
40 
41  void sift_down(int i) {
42  if (nelems <= 1) return;
43 
44  size_t parent, left, right, temp_idx = i;
45  Event* temp;
46 
47  /* Stops when neither child is "strictly less than" parent */
48  do {
49  parent = temp_idx;
50  left = LEFT(parent);
51  right = RIGHT(parent);
52  if (left < nelems && comparator(elems[left], elems[temp_idx])) temp_idx = left;
53  if (right < nelems && comparator(elems[right], elems[temp_idx])) temp_idx = right;
54  if (parent != temp_idx) SWAP(parent, temp_idx, temp);
55  } while (parent != temp_idx);
56  }
57 
58  void percolate_up( int i ) {
59  if (nelems <= 1) return;
60 
61  int child, parent, temp_idx = i;
62  Event* temp;
63 
64  /* Stops when parent is "less than or equal to" child */
65  do {
66  child = temp_idx;
67  parent = PARENT(child);
68  if (parent >= 0 && comparator(elems[temp_idx], elems[parent])) temp_idx = parent;
69  if (child != temp_idx) SWAP(child, temp_idx, temp);
70  } while (child != temp_idx);
71  }
72 
73  public:
74  PendingHeap() {
75  int init_size = HEAP_INCREMENT;
76  nelems = 0;
77  curr_max = (2*init_size);
78  int err = posix_memalign((void**)&elems, 64, sizeof(Event*)*curr_max);
79  memset(elems, 0, sizeof(Event*) * curr_max);
80  }
81 
82  PendingHeap(int init_size) {
83  nelems = 0;
84  curr_max = (2*init_size);
85  int err = posix_memalign((void**)&elems, 64, sizeof(Event*)*curr_max);
86  memset(elems, 0, sizeof(Event**) * curr_max);
87  }
88 
89  ~PendingHeap() {
90  for (int i = 0; i < nelems; i++) {
91  tw_event_free(elems[i],false);
92  }
93  delete[] elems;
94  }
95 
96  virtual void pup(PUP::er& p) {
97  p | nelems;
98  p | curr_max;
99  if (p.isUnpacking()) {
100  int err = posix_memalign((void**)&elems, 64, sizeof(Event*)*curr_max);
101  memset(elems, 0, sizeof(Event**) * curr_max);
102  }
103  for (int i = 0; i < nelems; i++) {
104  if (p.isUnpacking()) {
105  elems[i] = event_alloc();
106  }
107  elems[i]->pup(p);
108  }
109  }
110 
111  Event** get_temp_event_buffer() {
112  return elems;
113  }
114 
115  void delete_temp_event_buffer() {
116  }
117 
118  Time min() const {
119  return (nelems <= 0) ? TIME_MAX : elems[0]->ts;
120  }
121 
122  size_t size() const {
123  return nelems;
124  }
125 
126  void push(Event* e) {
127  if (nelems >= curr_max) {
128  size_t old_max = curr_max;
129  curr_max += HEAP_INCREMENT;
130  Event** old = elems;
131  int err = posix_memalign((void**)&elems, 64, sizeof(Event**)*curr_max);
132  memcpy(elems, old, sizeof(Event**) * old_max);
133  memset(&elems[old_max], 0, sizeof(Event**) * HEAP_INCREMENT);
134  free(old);
135  }
136 
137  e->state.owner = TW_chare_q;
138  e->index = nelems;
139 
140  elems[nelems++] = e;
141  percolate_up(nelems-1);
142  }
143 
144  Event* pop() {
145  if (nelems <= 0) {
146  return NULL;
147  } else {
148  Event* e = elems[0];
149  e->state.owner = 0;
150 
151  nelems--;
152  elems[0] = elems[nelems];
153  elems[0]->index = 0;
154  elems[nelems] = NULL;
155  sift_down(0);
156 
157  return e;
158  }
159  }
160 
161  void erase(Event* victim) {
162  TW_ASSERT(nelems > 0, "Can't erase from an empty heap\n");
163  TW_ASSERT(victim->index >= 0 && victim->index < nelems,
164  "Invalid heap index in erase\n");
165  TW_ASSERT(elems[victim->index]->index == victim->index,
166  "Mismatch in heap indices during erase\n");
167 
168  int i = victim->index;
169  nelems--;
170 
171  if (i == nelems) {
172  elems[nelems] = NULL;
173  return;
174  } else if (nelems > 0) {
175  elems[i] = elems[nelems];
176  elems[i]->index = i;
177  elems[nelems] = NULL;
178 
179  if (elems[i]->ts <= victim->ts) {
180  percolate_up(i);
181  } else {
182  sift_down(i);
183  }
184  }
185  }
186 };
187 #endif
188 
unsigned char owner
Which queue I am in; see tw_event_owner.
Definition: event.h:64
Definition: event.h:120
Definition: pending_queue.h:3
Definition: pending_heap.h:34
Event * event_alloc(RemoteEvent *event, uint64_t dest_gid, Time offset, LPBase *sender)
Send a previously allocated event.
Definition: event.C:47
Definition: event.h:232
Declares most types used within the simulator and by models.
In the chare&#39;s pending queue.
Definition: event.h:58