Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 09af48e

Browse files
committed
Skeleton reworked.
1 parent d8354e3 commit 09af48e

File tree

1 file changed

+44
-35
lines changed

1 file changed

+44
-35
lines changed

src/shard.c

Lines changed: 44 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
#include "shard.h"
1717
#include "timeutils.h"
1818

19+
/* epoll max events */
20+
#define MAX_EVENTS 64
21+
1922
typedef enum
2023
{
2124
MOVEMPART_IN_PROGRESS,
@@ -55,7 +58,7 @@ typedef struct
5558
static void init_mmp_state(MoveMPartState *mmps, const char *part_name,
5659
int32 dst_node);
5760
static void move_mparts(MoveMPartState *mmpss, int nparts);
58-
static int calc_timeout(slist_head *timeout_states);
61+
static int calc_timeout(struct timespec waketm, bool waketm_set);
5962
static ExecMoveMPartRes exec_move_mpart(MoveMPartState *mmps);
6063

6164
/*
@@ -260,18 +263,28 @@ move_mparts(MoveMPartState *mmpss, int nparts)
260263
/* list of sleeping mmp states we need to wake after specified timeout */
261264
slist_head timeout_states = SLIST_STATIC_INIT(timeout_states);
262265
slist_iter iter;
263-
264-
int timeout; /* at least one task will be ready after timeout millis */
266+
/* at least one task will require our attention at waketm */
267+
struct timespec waketm;
268+
/* Yes, we could use field of waketm for that. */
269+
bool waketm_set;
270+
int timeout;
265271
int unfinished_moves = 0; /* number of not yet failed or succeeded tasks */
266272
int i;
267273
int e;
268274
int epfd;
275+
struct epoll_event evlist[MAX_EVENTS];
269276

277+
/* In the beginning, all tasks are ready for execution, so wake tm is right
278+
* is actually current time. We also need to put all tasks to the
279+
* timeout_states list to invoke them.
280+
*/
281+
if ((e = clock_gettime(CLOCK_MONOTONIC, &waketm)) == -1)
282+
shmn_elog(FATAL, "clock_gettime failed, %s", strerror(e));
283+
waketm_set = true;
270284
for (i = 0; i < nparts; i++)
271285
{
272286
if (mmpss[i].result != MOVEMPART_FAILED)
273287
{
274-
/* In the beginning, all tasks are ready immediately */
275288
MoveMPartStateNode *mmps_node = palloc(sizeof(MoveMPartStateNode));
276289
elog(DEBUG4, "Adding task %s to timeout list", mmpss[i].part_name);
277290
mmps_node->mmps = &mmpss[i];
@@ -285,50 +298,46 @@ move_mparts(MoveMPartState *mmpss, int nparts)
285298
shmn_elog(FATAL, "epoll_create1 failed");
286299
}
287300

301+
/* TODO: check for signals */
288302
while (unfinished_moves > 0)
289303
{
290-
timeout = calc_timeout(&timeout_states);
304+
timeout = calc_timeout(waketm, waketm_set);
305+
e = epoll_wait(epfd, evlist, MAX_EVENTS, timeout);
306+
if (e == -1)
307+
{
308+
if (errno == EINTR)
309+
continue;
310+
else
311+
shmn_elog(FATAL, "epoll_wait failed, %s", strerror(e));
312+
}
291313
unfinished_moves--;
292314
}
293315
}
294316

295-
/* Calculate when we need to wake if no epoll events are happening */
317+
/*
318+
* Calculate when we need to wake if no epoll events are happening.
319+
* Returned value is ready for epoll_wait.
320+
*/
296321
int
297-
calc_timeout(slist_head *timeout_states)
322+
calc_timeout(struct timespec waketm, bool waketm_set)
298323
{
299-
slist_iter iter;
300-
struct timespec curtm;
301324
int e;
302-
int timeout = -1; /* If no tasks wait for us, don't wake */
325+
struct timespec curtm;
326+
int timeout;
303327

304-
slist_foreach(iter, timeout_states)
305-
{
306-
MoveMPartStateNode *mmps_node =
307-
slist_container(MoveMPartStateNode, list_node, iter.cur);
308-
MoveMPartState *mmps = mmps_node->mmps;
309-
shmn_elog(DEBUG1, "Peeking into %s task wake time", mmps->part_name);
310-
if ((e = clock_gettime(CLOCK_MONOTONIC, &curtm)) == -1)
311-
{
328+
if (!waketm_set)
329+
return -1;
330+
331+
if ((e = clock_gettime(CLOCK_MONOTONIC, &curtm)) == -1)
312332
shmn_elog(FATAL, "clock_gettime failed, %s", strerror(e));
313-
}
314-
if (timespeccmp(curtm, mmps->waketm) >= 0)
315-
{
316-
shmn_elog(DEBUG1, "Task %s is already ready", mmps->part_name);
317-
timeout = 0;
318-
return timeout;
319-
}
320-
else
321-
{
322-
int diff = Max(0, timespec_diff_millis(mmps->waketm, curtm));
323-
if (timeout == -1)
324-
timeout = diff;
325-
else
326-
timeout = Min(timeout, diff);
327-
shmn_elog(DEBUG1, "Timeout set to %d due to task %s ",
328-
timeout, mmps->part_name);
329-
}
333+
if (timespeccmp(waketm, curtm) <= 0)
334+
{
335+
shmn_elog(DEBUG1, "Non-negative timeout, waking immediately");
336+
return 0;
330337
}
331338

339+
timeout = Max(0, timespec_diff_millis(waketm, curtm));
340+
shmn_elog(DEBUG1, "Timeout is %d", timeout);
332341
return timeout;
333342
}
334343

0 commit comments

Comments
 (0)