Initial commit to the PapyrusRT repository.
This is the initial commit as submitted to CQ 9646.
The repository contains two top-level folders:
- codegen: the code-generator
- rts: the run-time system
Also-by: Andrew Eidsness, Zeligsoft contractor, andrewe@jfront.com,
Barry Maher, Zeligsoft contractor, bmaher@gpinc.ca, Ernesto Posse,
Zeligsoft, eposse@zeligsoft.com, Tim McGuire, Zeligsoft,
tmcguire@zeligsoft.com, Young-Soo Roh, Zeligsoft, ysroh@zeligsoft.com,
Toby McClean, Zeligsoft, toby@zeligsoft.com, Charles Rivet, Zeligsoft,
charles@zeligsoft.com, Andreas Henriksson, Ericsson,
andreas.henriksson@ericsson.com, Akos Horvath, IncQuery Labs,
akos.horvath@incquerylabs.com, Gabor Batori, Ericsson,
Gabor.Batori@ericsson.com, Abel Hegedus, IncQuery Labs,
abel.hegedus@incquerylabs.com, Denes Harmath, IncQuery Labs,
harmathdenes@gmail.com
Signed-off-by: Ernesto Posse <eposse@gmail.com>
diff --git a/rts/umlrt/umlrttimespec.cc b/rts/umlrt/umlrttimespec.cc
new file mode 100644
index 0000000..9589b82
--- /dev/null
+++ b/rts/umlrt/umlrttimespec.cc
@@ -0,0 +1,205 @@
+// umlrttimerspec.cc
+
+/*******************************************************************************
+* Copyright (c) 2014-2015 Zeligsoft (2009) Limited and others.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*******************************************************************************/
+
+#include "umlrttimespec.hh"
+#include "basefatal.hh"
+#include <sys/time.h>
+#include <time.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+UMLRTTimespec::UMLRTTimespec( const UMLRTTimespec & tm ) : tv_sec(tm.tv_sec), tv_nsec(tm.tv_nsec) { }
+
+UMLRTTimespec::UMLRTTimespec( long seconds, long nanoseconds ): tv_sec(seconds), tv_nsec(nanoseconds)
+{
+ timespecAdjust(this);
+}
+
+UMLRTTimespec::UMLRTTimespec() { UMLRTTimespec::getClock(this); }
+
+UMLRTTimespec & UMLRTTimespec::operator=( const UMLRTTimespec & tm )
+{
+ tv_sec = tm.tv_sec;
+ tv_nsec = tm.tv_nsec;
+
+ return *this;
+}
+
+bool UMLRTTimespec::operator==( const UMLRTTimespec & tm ) const
+{
+ return (tv_sec == tm.tv_sec) && (tv_nsec == tm.tv_nsec);
+}
+
+bool UMLRTTimespec::operator!=( const UMLRTTimespec & tm ) const
+{
+ return (tv_sec != tm.tv_sec) || (tv_nsec != tm.tv_nsec);
+}
+
+bool UMLRTTimespec::operator<( const UMLRTTimespec & tm ) const
+{
+ if (tv_sec < tm.tv_sec)
+ return true;
+
+ else if (tv_sec == tm.tv_sec)
+ return (tv_nsec < tm.tv_nsec);
+
+ return false;
+}
+
+bool UMLRTTimespec::operator<=( const UMLRTTimespec & tm ) const
+{
+ if (tv_sec < tm.tv_sec)
+ return true;
+
+ else if (tv_sec == tm.tv_sec)
+ return (tv_nsec <= tm.tv_nsec);
+
+ return false;
+}
+
+bool UMLRTTimespec::operator>( const UMLRTTimespec & tm ) const
+{
+ if (tv_sec > tm.tv_sec)
+ return true;
+
+ else if (tv_sec == tm.tv_sec)
+ return (tv_nsec > tm.tv_nsec);
+
+ return false;
+}
+
+bool UMLRTTimespec::operator>=( const UMLRTTimespec & tm ) const
+{
+ if (tv_sec > tm.tv_sec)
+ return true;
+
+ else if (tv_sec == tm.tv_sec)
+ return (tv_nsec >= tm.tv_nsec);
+
+ return false;
+}
+
+// Ensure tv_nsec is always 0..999999999.
+/*static*/ void UMLRTTimespec::timespecAdjust( UMLRTTimespec * tm )
+{
+ // Times must be adjusted after a single add/subtract, so tv_nsec is assumed to be
+ // between -999999999 and 2*999999999 before it is adjusted.
+ // We do a sanity check after the adjustment to confirm our assumptions are correct.
+ if (tm->tv_nsec > ONE_BILLION)
+ {
+ tm->tv_sec += 1;
+ tm->tv_nsec -= ONE_BILLION;
+ }
+ if (tm->tv_nsec < 0)
+ {
+ tm->tv_sec -= 1;
+ tm->tv_nsec += ONE_BILLION;
+ }
+ // For now, we FATAL() if tm->tv_nsec was not sufficiently adjusted.
+ if (tm->tv_nsec > ONE_BILLION)
+ {
+ FATAL("time tv_nsec(%ld) > ONE_BILLION", tm->tv_nsec);
+ }
+ if (tm->tv_nsec < 0)
+ {
+ FATAL("time tv_nsec(%ld) < 0", tm->tv_nsec);
+ }
+}
+
+UMLRTTimespec UMLRTTimespec::operator+( const UMLRTTimespec & tm ) const
+{
+ return UMLRTTimespec(tv_sec + tm.tv_sec, tv_nsec + tm.tv_nsec);
+}
+
+UMLRTTimespec UMLRTTimespec::operator-( const UMLRTTimespec & tm ) const
+{
+ return UMLRTTimespec(tv_sec - tm.tv_sec, tv_nsec - tm.tv_nsec);
+}
+
+UMLRTTimespec & UMLRTTimespec::operator+=( const UMLRTTimespec & tm )
+{
+ tv_sec += tm.tv_sec;
+ tv_nsec += tm.tv_nsec;
+
+ timespecAdjust(this);
+
+ return *this;
+}
+
+UMLRTTimespec & UMLRTTimespec::operator-=( const UMLRTTimespec & tm )
+{
+ tv_sec -= tm.tv_sec;
+ tv_nsec -= tm.tv_nsec;
+
+ timespecAdjust(this);
+
+ return *this;
+}
+
+/*static*/ void UMLRTTimespec::getClock( UMLRTTimespec * tm )
+{
+ // Linux-specific for now.
+ struct timeval tv;
+
+ if (gettimeofday(&tv, NULL) < 0)
+ {
+ FATAL_ERRNO("gettimeofday");
+ }
+ tm->tv_sec = tv.tv_sec;
+ tm->tv_nsec = tv.tv_usec * 1000;
+}
+
+bool UMLRTTimespec::isZeroOrNegative() const
+{
+ return (tv_sec < 0) || ((tv_sec == 0) && (tv_nsec == 0));
+}
+
+char * UMLRTTimespec::toString( char * buffer, int size ) const
+{
+ struct tm from_localtime;
+ const time_t seconds = tv_sec;
+
+ localtime_r( &seconds, &from_localtime );
+
+ size_t length = strftime(buffer, size, "%Y-%m-%d:%H:%M:%S", &from_localtime);
+ long msec = tv_nsec / NANOSECONDS_PER_MILLISECOND;
+ snprintf( &buffer[length], size-length, ".%03ld", msec );
+
+ return buffer;
+}
+
+char * UMLRTTimespec::toStringRelative( char * buffer, int size ) const
+{
+ long int seconds = tv_sec;
+ long int days = seconds / SECONDS_PER_DAY;
+ seconds -= (days * SECONDS_PER_DAY);
+ long int hours = seconds / SECONDS_PER_HOUR;
+ seconds -= (hours * SECONDS_PER_HOUR);
+ long int minutes = seconds / SECONDS_PER_MINUTE;
+ seconds -= (minutes * SECONDS_PER_MINUTE);
+
+ long int msec = tv_nsec / NANOSECONDS_PER_MILLISECOND;
+
+ snprintf( buffer, size, "%ld:%02ld:%02ld:%02ld.%03ld", days, hours, minutes, seconds, msec );
+
+ return buffer;
+}
+
+/*static*/ void UMLRTTimespec::timespecAbsAddMsec( struct timespec * timeout, long msec )
+{
+ clock_gettime(CLOCK_REALTIME, timeout);
+ timeout->tv_sec += (msec / 1000);
+ timeout->tv_nsec += (msec % 1000) * ONE_BILLION;
+ if (timeout->tv_nsec >= ONE_BILLION)
+ {
+ timeout->tv_sec += 1;
+ timeout->tv_nsec -= ONE_BILLION;
+ }
+}