static void message_notification(int signum, siginfo_t *si, void *notused)
{
Tachyon *tp = (Tachyon *) si->si_value.sival_ptr;
+ //printf("Tachyon: Caught signal %d\n", signum);
tp->receive_message();
tp->expect_message();
}
accelleration = 1.0;
+ msg_sequence = 0;
+
struct mq_attr queue_attributes;
struct sigevent sev;
struct sigaction act;
accelleration = 1.0;
+ msg_sequence = 0;
+
queue_name[0] = '\0';
msg_queue = mq_open(name, O_WRONLY);
}
int message_size;
//printf("Receiving message.\n");
+
message_size = mq_receive(msg_queue, message, MAX_MESSAGE_SIZE, NULL);
+ msg_sequence++;
+
+ //printf("Message size = %d\n", message_size);
message[message_size] = '\0';
//printf("The message is %s.\n", message);
// Tvirtual = T0 + acc * (Tactual - T0) + offset
- difference = timespec_subtract(actual_time, T0);
+ difference = actual_time - T0;
//printf(" Ta - T0 = %d,%d\n", difference.tv_sec, difference.tv_nsec);
seconds = difference.tv_sec * accelleration;
difference.tv_nsec = trunc(nanoseconds);
//printf(" a * (Ta - T0) = %d,%d\n", difference.tv_sec, difference.tv_nsec);
- virtual_time = timespec_add(T0, difference);
- virtual_time = timespec_add(virtual_time, offset);
+ virtual_time = T0 + difference + offset;
return virtual_time;
}
virt_time = gettime();
- return sleep_until(timespec_add(virt_time, req));
+ return sleep_until(virt_time + req);
}
int Tachyon::nanosleep(float req)
double seconds;
double nanoseconds;
int sleep_return;
- bool error;
+ int last_msg_sequence;
timespec virt_time;
timespec remaining;
+ last_msg_sequence = msg_sequence;
+ sleep_return = 0;
+
virt_time = gettime();
- while (!error && virt_time < ends_at)
+ while (sleep_return == 0 && virt_time < ends_at)
{
timespec period;
sleep_return = ::nanosleep(&period, &remaining);
//printf("nanosleep returns %d, error = %s\n", sleep_return, strerror(errno));
- error = sleep_return == -1 && errno != EINTR;
+ // If a sleep interruption is caused by receiving a message, the sleep is resumed.
+ if (sleep_return == -1 && errno == EINTR)
+ {
+ if (msg_sequence != last_msg_sequence)
+ {
+ sleep_return = 0;
+ last_msg_sequence = msg_sequence;
+ }
+ else
+ {
+ sleep_return = -2; // Interrupted by a different signal
+ }
+ }
+
virt_time = gettime();
}