Skip to content

Commit 9b1ce4f

Browse files
authored
Merge branch 'cooperative-computing-lab:master' into rename_vine_log
2 parents c79d7dc + 1875bd2 commit 9b1ce4f

22 files changed

+500
-112
lines changed

dttools/src/debug.c

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,11 @@ extern int debug_file_reopen(void);
3434
extern int debug_file_close(void);
3535

3636
static void (*debug_write)(int64_t flags, const char *str) = debug_stderr_write;
37-
static pid_t (*debug_getpid)(void) = getpid;
37+
static pid_t (*debug_child_getpid)(void) = 0;
3838
static char debug_program_name[PATH_MAX];
3939
static int64_t debug_flags = D_NOTICE | D_ERROR | D_FATAL;
40+
static pid_t debug_cached_pid = 0;
41+
static int debug_time_zone_cached = 0;
4042

4143
struct flag_info {
4244
const char *name;
@@ -182,20 +184,37 @@ static void do_debug(int64_t flags, const char *fmt, va_list args)
182184
gettimeofday(&tv, 0);
183185
tm = localtime(&tv.tv_sec);
184186

187+
/*
188+
If the TZ environment variable is not set, then every single call
189+
to localtime() results in a stat("/etc/localtime") which impacts
190+
the minimum latency of a debug event.
191+
*/
192+
193+
if (!debug_time_zone_cached) {
194+
if (!getenv("TZ")) {
195+
setenv("TZ", tm->tm_zone, 0);
196+
}
197+
debug_time_zone_cached = 1;
198+
}
199+
200+
/* Fetch the pid just once and use it multiple times. */
201+
pid_t pid = getpid();
202+
185203
buffer_putfstring(&B,
186-
"%04d/%02d/%02d %02d:%02d:%02d.%02ld ",
204+
"%04d/%02d/%02d %02d:%02d:%02d.%02ld %s[%d]",
187205
tm->tm_year + 1900,
188206
tm->tm_mon + 1,
189207
tm->tm_mday,
190208
tm->tm_hour,
191209
tm->tm_min,
192210
tm->tm_sec,
193-
(long)tv.tv_usec / 10000);
194-
buffer_putfstring(&B, "%s[%d] ", debug_program_name, getpid());
211+
(long)tv.tv_usec / 10000,
212+
debug_program_name,
213+
pid);
195214
}
196215
/* Parrot prints debug messages for children: */
197-
if (getpid() != debug_getpid()) {
198-
buffer_putfstring(&B, "<child:%d> ", (int)debug_getpid());
216+
if (debug_child_getpid) {
217+
buffer_putfstring(&B, "<child:%d> ", (int)debug_child_getpid());
199218
}
200219
buffer_putfstring(&B, "%s: ", debug_flags_to_name(flags));
201220

@@ -309,16 +328,17 @@ void debug_config_file(const char *path)
309328
void debug_config(const char *name)
310329
{
311330
strncpy(debug_program_name, path_basename(name), sizeof(debug_program_name) - 1);
331+
debug_cached_pid = getpid();
312332
}
313333

314334
void debug_config_file_size(off_t size)
315335
{
316336
debug_file_size(size);
317337
}
318338

319-
void debug_config_getpid(pid_t (*getpidf)(void))
339+
void debug_config_child_getpid(pid_t (*getpidf)(void))
320340
{
321-
debug_getpid = getpidf;
341+
debug_child_getpid = getpidf;
322342
}
323343

324344
int64_t debug_flags_clear()

dttools/src/debug.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ modify the linker namespace we are using.
124124
#define debug_config_file cctools_debug_config_file
125125
#define debug_config_file_size cctools_debug_config_file_size
126126
#define debug_config_fatal cctools_debug_config_fatal
127-
#define debug_config_getpid cctools_debug_config_getpid
127+
#define debug_config_child_getpid cctools_debug_config_child_getpid
128128
#define debug_flags_set cctools_debug_flags_set
129129
#define debug_flags_print cctools_debug_flags_print
130130
#define debug_flags_clear cctools_debug_flags_clear
@@ -206,7 +206,7 @@ void debug_config_file_size(off_t size);
206206

207207
void debug_config_fatal(void (*callback) (void));
208208

209-
void debug_config_getpid (pid_t (*getpidf)(void));
209+
void debug_config_child_getpid (pid_t (*getpidf)(void));
210210

211211
/** Set debugging flags to enable output.
212212
Accepts a debug flag in ASCII form, and enables that subsystem. For example: <tt>debug_flags_set("chirp");</tt>

dttools/src/priority_queue.c

Lines changed: 43 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ See the file COPYING for details.
1313
#include <float.h>
1414

1515
#define DEFAULT_CAPACITY 127
16-
#define MAX_PRIORITY DBL_MAX
17-
#define MIN_PRIORITY DBL_MIN
1816

1917
struct element {
2018
void *data;
@@ -27,8 +25,8 @@ struct priority_queue {
2725
struct element **elements;
2826

2927
/* The following three cursors are used to iterate over the elements in the numerical order they are stored in the array, which is
30-
different from the order of priorities. Each of them has different concerns when traverse the queue Though the tipical priority-based
31-
traversal is done by the repeated invocation of priority_queue_peak_top and priority_queue_pop APIs, rather than using any cursors. */
28+
different from the order of priorities. Each of them has different concerns when traverse the queue Though the typical priority-based
29+
traversal is done by the repeated invocation of priority_queue_peek_top and priority_queue_pop APIs, rather than using any cursors. */
3230
int base_cursor; // Used in PRIORITY_QUEUE_BASE_ITERATE. It iterates from the first position and never be reset automatically.
3331
int static_cursor; // Used in PRIORITY_QUEUE_STATIC_ITERATE. It iterates from the last position and never be reset automatically.
3432
int rotate_cursor; // Used in PRIORITY_QUEUE_ROTATE_ITERATE. It iterates from the last position and can be reset when certain events happen.
@@ -101,7 +99,7 @@ static int priority_queue_double_capacity(struct priority_queue *pq)
10199

102100
/****** External Methods ******/
103101

104-
struct priority_queue *priority_queue_create(double init_capacity)
102+
struct priority_queue *priority_queue_create(int init_capacity)
105103
{
106104
struct priority_queue *pq = (struct priority_queue *)malloc(sizeof(struct priority_queue));
107105
if (!pq) {
@@ -142,17 +140,17 @@ int priority_queue_size(struct priority_queue *pq)
142140
int priority_queue_push(struct priority_queue *pq, void *data, double priority)
143141
{
144142
if (!pq) {
145-
return 0;
143+
return -1;
146144
}
147145

148146
if (pq->size >= pq->capacity) {
149147
if (!priority_queue_double_capacity(pq)) {
150-
return 0;
148+
return -1;
151149
}
152150
}
153151
struct element *e = (struct element *)malloc(sizeof(struct element));
154152
if (!e) {
155-
return 0;
153+
return -1;
156154
}
157155
e->data = data;
158156
e->priority = priority;
@@ -185,7 +183,7 @@ void *priority_queue_pop(struct priority_queue *pq)
185183
return data;
186184
}
187185

188-
void *priority_queue_peak_top(struct priority_queue *pq)
186+
void *priority_queue_peek_top(struct priority_queue *pq)
189187
{
190188
if (!pq || pq->size == 0) {
191189
return NULL;
@@ -203,7 +201,7 @@ double priority_queue_get_priority(struct priority_queue *pq, int idx)
203201
return pq->elements[idx]->priority;
204202
}
205203

206-
void *priority_queue_peak_at(struct priority_queue *pq, int idx)
204+
void *priority_queue_peek_at(struct priority_queue *pq, int idx)
207205
{
208206
if (!pq || pq->size < 1 || idx < 0 || idx > pq->size - 1) {
209207
return NULL;
@@ -215,7 +213,7 @@ void *priority_queue_peak_at(struct priority_queue *pq, int idx)
215213
int priority_queue_update_priority(struct priority_queue *pq, void *data, double new_priority)
216214
{
217215
if (!pq) {
218-
return 0;
216+
return -1;
219217
}
220218

221219
int idx = -1;
@@ -226,8 +224,9 @@ int priority_queue_update_priority(struct priority_queue *pq, void *data, double
226224
}
227225
}
228226

227+
/* If the data isn’t already in the queue, enqueue it. */
229228
if (idx == -1) {
230-
return 0;
229+
return priority_queue_push(pq, data, new_priority);
231230
}
232231

233232
double old_priority = pq->elements[idx]->priority;
@@ -247,7 +246,7 @@ int priority_queue_update_priority(struct priority_queue *pq, void *data, double
247246
int priority_queue_find_idx(struct priority_queue *pq, void *data)
248247
{
249248
if (!pq) {
250-
return 0;
249+
return -1;
251250
}
252251

253252
for (int i = 0; i < pq->size; i++) {
@@ -256,13 +255,13 @@ int priority_queue_find_idx(struct priority_queue *pq, void *data)
256255
}
257256
}
258257

259-
return 0;
258+
return -1;
260259
}
261260

262261
int priority_queue_static_next(struct priority_queue *pq)
263262
{
264263
if (!pq || pq->size == 0) {
265-
return 0;
264+
return -1;
266265
}
267266

268267
int static_idx = pq->static_cursor;
@@ -291,7 +290,7 @@ Advance the base cursor and return it, should be used only in PRIORITY_QUEUE_BAS
291290
int priority_queue_base_next(struct priority_queue *pq)
292291
{
293292
if (!pq || pq->size == 0) {
294-
return 0;
293+
return -1;
295294
}
296295

297296
int base_idx = pq->base_cursor;
@@ -316,7 +315,7 @@ void priority_queue_rotate_reset(struct priority_queue *pq)
316315
int priority_queue_rotate_next(struct priority_queue *pq)
317316
{
318317
if (!pq || pq->size == 0) {
319-
return 0;
318+
return -1;
320319
}
321320

322321
int rotate_idx = pq->rotate_cursor;
@@ -335,26 +334,40 @@ int priority_queue_remove(struct priority_queue *pq, int idx)
335334
return 0;
336335
}
337336

338-
struct element *e = pq->elements[idx];
339-
pq->size--;
340-
pq->elements[idx] = pq->elements[pq->size];
341-
pq->elements[pq->size] = NULL;
337+
struct element *to_delete = pq->elements[idx];
338+
struct element *last_elem = pq->elements[pq->size - 1];
339+
340+
double old_priority = to_delete->priority;
341+
double new_priority = last_elem->priority;
342342

343-
sink(pq, idx);
343+
free(to_delete);
344344

345-
if (pq->static_cursor == idx) {
345+
pq->size--;
346+
if (idx != pq->size) {
347+
pq->elements[idx] = last_elem;
348+
pq->elements[pq->size] = NULL;
349+
350+
if (new_priority > old_priority) {
351+
swim(pq, idx);
352+
} else if (new_priority < old_priority) {
353+
sink(pq, idx);
354+
}
355+
} else {
356+
pq->elements[pq->size] = NULL;
357+
}
358+
359+
if (pq->static_cursor == idx && pq->static_cursor > 0) {
346360
pq->static_cursor--;
347361
}
348-
if (pq->base_cursor == idx) {
362+
if (pq->base_cursor == idx && pq->base_cursor > 0) {
349363
pq->base_cursor--;
350364
}
351-
if (pq->rotate_cursor == idx) {
365+
if (pq->rotate_cursor == idx && pq->rotate_cursor > 0) {
352366
pq->rotate_cursor--;
353367
}
354-
free(e);
355368

369+
// reset the rotate cursor if the removed element is before/equal to it
356370
if (idx <= pq->rotate_cursor) {
357-
// reset the rotate cursor if the removed element is before/equal to it
358371
priority_queue_rotate_reset(pq);
359372
}
360373

@@ -368,7 +381,9 @@ void priority_queue_delete(struct priority_queue *pq)
368381
}
369382

370383
for (int i = 0; i < pq->size; i++) {
371-
free(pq->elements[i]);
384+
if (pq->elements[i]) {
385+
free(pq->elements[i]);
386+
}
372387
}
373388
free(pq->elements);
374389
free(pq);

dttools/src/priority_queue.h

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,13 @@ void *data = someDataPointer;
6464
6565
priority_queue_push(pq, data, priority);
6666
data = priority_queue_pop(pq);
67-
void *headData = priority_queue_peak_top(pq);
67+
void *headData = priority_queue_peek_top(pq);
6868
</pre>
6969
7070
To list all of the items in a priority queue, use a simple loop:
7171
<pre>
7272
for (int i = 0; i < priority_queue_size(pq); i++) {
73-
void *data = priority_queue_peak_at(pq, i);
73+
void *data = priority_queue_peek_at(pq, i);
7474
printf("Priority queue contains: %p\n", data);
7575
}
7676
</pre>
@@ -94,7 +94,7 @@ Element with a higher priority is at the top of the heap.
9494
@param init_capacity The initial number of elements in the queue. If zero, a default value will be used.
9595
@return A pointer to a new priority queue.
9696
*/
97-
struct priority_queue *priority_queue_create(double init_capacity);
97+
struct priority_queue *priority_queue_create(int init_capacity);
9898

9999
/** Count the elements in a priority queue.
100100
@param pq A pointer to a priority queue.
@@ -122,15 +122,15 @@ Similar to @ref priority_queue_pop, but the element is not removed.
122122
@param pq A pointer to a priority queue.
123123
@return The pointer to the top of the queue if any, failure otherwise
124124
*/
125-
void *priority_queue_peak_top(struct priority_queue *pq);
125+
void *priority_queue_peek_top(struct priority_queue *pq);
126126

127127
/** Get an element from a priority queue by a specified index.
128128
The first accessible element is at index 0.
129129
@param pq A pointer to a priority queue.
130130
@param index The index of the element to get.
131131
@return The pointer to the element if any, failure otherwise
132132
*/
133-
void *priority_queue_peak_at(struct priority_queue *pq, int index);
133+
void *priority_queue_peek_at(struct priority_queue *pq, int index);
134134

135135
/** Get the priority of an element at a specified index.
136136
@param pq A pointer to a priority queue.
@@ -150,15 +150,15 @@ int priority_queue_update_priority(struct priority_queue *pq, void *data, double
150150
/** Find the index of an element in a priority queue.
151151
@param pq A pointer to a priority queue.
152152
@param data The pointer to the element to find.
153-
@return The index of the element if found, 0 on failure.
153+
@return The index of the element if found, -1 on failure.
154154
*/
155155
int priority_queue_find_idx(struct priority_queue *pq, void *data);
156156

157157
/** Advance the static_cursor to the next element and return the index.
158158
The static_cursor is used to globally iterate over the elements by sequential index.
159159
The position of the static_cursor is automatically remembered and never reset.
160160
@param pq A pointer to a priority queue.
161-
@return The index of the next element if any, 0 on failure.
161+
@return The index of the next element if any, -1 on failure.
162162
*/
163163
int priority_queue_static_next(struct priority_queue *pq);
164164

@@ -170,7 +170,7 @@ void priority_queue_base_reset(struct priority_queue *pq);
170170

171171
/** Advance the base_cursor to the next element and return the index.
172172
@param pq A pointer to a priority queue.
173-
@return The index of the next element if any, 0 on failure.
173+
@return The index of the next element if any, -1 on failure.
174174
*/
175175
int priority_queue_base_next(struct priority_queue *pq);
176176

@@ -185,7 +185,7 @@ void priority_queue_rotate_reset(struct priority_queue *pq);
185185

186186
/** Advance the rotate_cursor to the next element and return the index.
187187
@param pq A pointer to a priority queue.
188-
@return The index of the next element if any, 0 on failure.
188+
@return The index of the next element if any, -1 on failure.
189189
*/
190190
int priority_queue_rotate_next(struct priority_queue *pq);
191191

@@ -235,16 +235,16 @@ PRIORITY_QUEUE_ROTATE_ITERATE( pq, idx, data, iter_count, iter_depth ) {
235235
#define PRIORITY_QUEUE_BASE_ITERATE( pq, idx, data, iter_count, iter_depth ) \
236236
iter_count = 0; \
237237
priority_queue_base_reset(pq); \
238-
while ((iter_count < iter_depth) && ((idx = priority_queue_base_next(pq)) >= 0) && (data = priority_queue_peak_at(pq, idx)) && (iter_count += 1))
238+
while ((iter_count < iter_depth) && ((idx = priority_queue_base_next(pq)) >= 0) && (data = priority_queue_peek_at(pq, idx)) && (iter_count += 1))
239239

240240
/* Iterate from last position, never reset. */
241241
#define PRIORITY_QUEUE_STATIC_ITERATE( pq, idx, data, iter_count, iter_depth ) \
242242
iter_count = 0; \
243-
while ((iter_count < iter_depth) && ((idx = priority_queue_static_next(pq)) >= 0) && (data = priority_queue_peak_at(pq, idx)) && (iter_count += 1))
243+
while ((iter_count < iter_depth) && ((idx = priority_queue_static_next(pq)) >= 0) && (data = priority_queue_peek_at(pq, idx)) && (iter_count += 1))
244244

245245
/* Iterate from last position, reset to the begining when needed. */
246246
#define PRIORITY_QUEUE_ROTATE_ITERATE( pq, idx, data, iter_count, iter_depth ) \
247247
iter_count = 0; \
248-
while ((iter_count < iter_depth) && ((idx = priority_queue_rotate_next(pq)) >= 0) && (data = priority_queue_peak_at(pq, idx)) && (iter_count += 1))
248+
while ((iter_count < iter_depth) && ((idx = priority_queue_rotate_next(pq)) >= 0) && (data = priority_queue_peek_at(pq, idx)) && (iter_count += 1))
249249

250250
#endif

0 commit comments

Comments
 (0)