--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/genericopenlibs/openenvcore/libc/src/clock_funcs.cpp Tue Feb 02 02:01:42 2010 +0200
@@ -0,0 +1,234 @@
+/*
+* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: This is a project specific include file for building the
+* clock related functions as part of libc library.
+*
+*/
+
+
+#include <time.h>
+#include <errno.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <e32std.h>
+#include <sys/_timeval.h>
+#include <sys/types.h>
+#include "lposix.h"
+
+#define UNIX_BASE TTime(MAKE_TINT64(0x00dcddb3,0x0f2f8000)) // 00:00, Jan 1st 1970
+
+extern "C" {
+
+//Returns the resolution (granularity) of a clock
+//This value is placed in a (non-NULL) *res
+EXPORT_C int clock_getres(clockid_t clock_id, struct timespec* res)
+{
+ int retval = -1;
+ //We expect the user of the library to give us a valid pointer
+ if(res == NULL)
+ {
+ errno = EFAULT;
+ return retval;
+ }
+
+ switch (clock_id)
+ {
+ case CLOCK_REALTIME:
+ //Since Symbian OS is not realtime,we simulate the same using
+ //the available wall clock whose resolution is upto microseconds
+ res->tv_sec = 0;
+ res->tv_nsec = 1000000;
+ retval = 0;
+ break;
+
+ default:
+ //For all other clocks that cannot be supported or invalid clockids,
+ //we set errno to not-supported
+ retval = -1;
+ errno = EINVAL;
+ break;
+ }
+ return retval;
+}
+
+//Allow the calling process to retrieve the value used by a clock which
+//is specified by clock_id
+EXPORT_C int clock_gettime (clockid_t clock_id, struct timespec *tp)
+{
+ int retval = -1;
+ TTime t;
+ TTimeIntervalSeconds iSeconds;
+ TInt err;
+ //We expect the user of the library to give us a valid pointer
+ if(tp == NULL)
+ {
+ errno = EFAULT;
+ return retval;
+ }
+
+ switch(clock_id)
+ {
+ case CLOCK_REALTIME:
+ //Since Symbian OS is not realtime,we simulate the same using
+ //the available wall clock.We use TTime::HomeTime() call to get
+ //the wall clock time
+ t.HomeTime();
+ err = t.SecondsFrom(UNIX_BASE, iSeconds);
+ t-=iSeconds;//extracting seconds info into iSeconds
+ if (!err)
+ {
+ tp->tv_sec = iSeconds.Int();
+ tp->tv_nsec = t.Int64();
+ retval = 0;
+ }
+ break;
+
+ default:
+ //For all other clocks that cannot be supported or invalid clockids,
+ //we set errno to invalid
+ retval = -1;
+ errno = EINVAL;
+ break;
+ }
+ return retval;
+}
+
+
+//The clock_settime allow the calling process to set the value used by a
+//clock which is specified by clock_id
+EXPORT_C int clock_settime (clockid_t clock_id, const struct timespec *tp)
+{
+ int retval = -1;
+ TTime t(MAKE_TINT64 (0x00dcddb3 ,0x0f2f8000)) ; // 00:00, Jan 1st 1970
+ TInt err;
+ TInt64 microtime;
+ //We must get a filled structure from the user of the library
+ if(tp == NULL)
+ {
+ errno = EFAULT;
+ return retval;
+ }
+ //Check for boundary values of seconds and microseconds
+ if (tp->tv_nsec < 0 || tp->tv_nsec >= 1000000000L)
+ {
+ errno = ERANGE;
+ return retval;
+ }
+
+ switch(clock_id)
+ {
+ case CLOCK_REALTIME:
+ //We support only the wall-clock,hence use the
+ //User::SetHomeTime call to set the time
+ t+=(TTimeIntervalSeconds)tp->tv_sec;
+ microtime = (tp->tv_nsec)/1000;
+ t+=(TTimeIntervalMicroSeconds)microtime;
+ err = User::SetUTCTime(t);
+ if(err)
+ {
+ MapError(err,errno);
+ break;
+ }
+ else
+ retval = 0;
+ break;
+
+ default:
+ //For all other clocks that cannot be supported or invalid clockids,
+ //we set errno to invalid
+ retval = -1;
+ errno = EINVAL;
+ break;
+ }
+ return retval;
+}
+
+
+//Returns the clock ID of the CPU-time clock of the process specified by pid
+EXPORT_C int clock_getcpuclockid (pid_t pid, clockid_t *clock_id)
+{
+ int retval = -1;
+ /* We don't allow any process ID but our own. */
+ if (pid == 0)
+ {
+ //The only available clock is the realtime wall clock
+ //Hence we set the clockid to that
+ *clock_id = CLOCK_REALTIME;
+ retval = 0;
+ }
+ else
+ errno = ESRCH;
+
+ return retval;
+}
+
+//Makes small adjustments to the system time,
+//advancing it by the time specified by the timeval delta
+EXPORT_C int adjtime(const struct timeval *delta, struct timeval *olddelta)
+{
+ //We can make only positive adjutments to the available clock
+ //The synchronization to the global time server is provided to us
+ //by the User::SetHomeTime api itself
+ int retval = -1;
+ TTime t;
+ TInt err;
+ TInt64 microtime;
+ long secs = 0;
+ suseconds_t usec = 0;
+
+ //We expect the user of the library to give us a valid pointer
+ if(delta == NULL)
+ {
+ errno = EFAULT;
+ return retval;
+ }
+
+ if ((delta->tv_usec) > 1000000)
+ {
+ errno = ERANGE;
+ return retval;
+ }
+ //Check for negative of seconds and make it positive
+ if((delta->tv_sec) < 0)
+ secs = -1*(delta->tv_sec);
+ else
+ secs = delta->tv_sec;
+
+ //Check for negative of microseconds and make it positive
+ if((delta->tv_usec) < 0)
+ usec = -1*(delta->tv_usec);
+ else
+ usec = delta->tv_usec;
+
+ t.HomeTime();
+ t+=(TTimeIntervalSeconds)secs;
+ microtime = usec;
+ t+=(TTimeIntervalMicroSeconds)microtime;
+ err = User::SetHomeTime(t);
+ if (!err)
+ {
+ retval = 0;
+ //olddelta is always zero in case of success
+ olddelta->tv_sec = 0;
+ olddelta->tv_usec = 0;
+ }
+ else
+ {
+ MapError(err,errno);
+ retval = -1;
+ }
+ return retval;
+}
+
+} // extern "C"