1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/genericopenlibs/posixrealtimeextensions/src/clock_funcs.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,255 @@
1.4 +/*
1.5 +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
1.6 +* All rights reserved.
1.7 +* This component and the accompanying materials are made available
1.8 +* under the terms of "Eclipse Public License v1.0"
1.9 +* which accompanies this distribution, and is available
1.10 +* at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.11 +*
1.12 +* Initial Contributors:
1.13 +* Nokia Corporation - initial contribution.
1.14 +*
1.15 +* Contributors:
1.16 +*
1.17 +* Description: This is a project specific source file for building the
1.18 +* clock related functions as part of librt library.
1.19 +*
1.20 +*/
1.21 +
1.22 +
1.23 +#include <time.h>
1.24 +#include <errno.h>
1.25 +#include <pthread.h>
1.26 +#include <stdlib.h>
1.27 +#include <e32std.h>
1.28 +#include <sys/_timeval.h>
1.29 +#include <sys/types.h>
1.30 +
1.31 +#include "lposix.h"
1.32 +
1.33 +#define UNIX_BASE TTime(MAKE_TINT64(0x00dcddb3,0x0f2f8000)) // 00:00, Jan 1st 1970
1.34 +
1.35 +#define BOUNDARY_CHECK(rqtp) ( (rqtp->tv_nsec != 0 && rqtp->tv_nsec < 1000) || \
1.36 + rqtp->tv_nsec >= 1000000000L )\
1.37 +
1.38 +extern "C" {
1.39 +
1.40 +//Returns the resolution (granularity) of a clock
1.41 +//This value is placed in a (non-NULL) *res
1.42 +EXPORT_C int clock_getres(clockid_t clock_id, struct timespec* res)
1.43 +{
1.44 + int retval = -1;
1.45 + //We expect the user of the library to give us a valid pointer
1.46 + if(res == NULL)
1.47 + {
1.48 + return 0; //no strict reactions please.
1.49 + }
1.50 +
1.51 + switch (clock_id)
1.52 + {
1.53 + case CLOCK_REALTIME:
1.54 + //Since Symbian OS is not realtime,we simulate the same using
1.55 + //the available wall clock whose resolution is upto microseconds
1.56 + res->tv_sec = 0;
1.57 + res->tv_nsec = 1000;
1.58 + retval = 0;
1.59 + break;
1.60 +
1.61 + default:
1.62 + //For all other clocks that cannot be supported or invalid clockids,
1.63 + //we set errno to not-supported
1.64 + retval = -1;
1.65 + errno = EINVAL;
1.66 + break;
1.67 + }
1.68 +
1.69 + return retval;
1.70 +}
1.71 +
1.72 +//Allow the calling process to retrieve the value used by a clock which
1.73 +//is specified by clock_id
1.74 +EXPORT_C int clock_gettime (clockid_t clock_id, struct timespec *tp)
1.75 +{
1.76 + int retval = -1;
1.77 + TTime t;
1.78 + TTimeIntervalSeconds iSeconds;
1.79 + TInt err;
1.80 + //We expect the user of the library to give us a valid pointer
1.81 + if(tp == NULL)
1.82 + {
1.83 + errno = EFAULT;
1.84 + return retval;
1.85 + }
1.86 +
1.87 + switch(clock_id)
1.88 + {
1.89 + case CLOCK_REALTIME:
1.90 + //Since Symbian OS is not realtime,we simulate the same using
1.91 + //the available wall clock.We use TTime::HomeTime() call to get
1.92 + //the wall clock time
1.93 + t.HomeTime();
1.94 + err = t.SecondsFrom(UNIX_BASE, iSeconds); //TODO check for the negative tests..
1.95 + if (!err)
1.96 + {
1.97 + t-=iSeconds;//extracting seconds info into iSeconds
1.98 + tp->tv_sec = iSeconds.Int();
1.99 + tp->tv_nsec = t.Int64();
1.100 + retval = 0;
1.101 + }
1.102 + break;
1.103 +
1.104 + default:
1.105 + //For all other clocks that cannot be supported or invalid clockids,
1.106 + //we set errno to invalid
1.107 + retval = -1;
1.108 + errno = EINVAL;
1.109 + break;
1.110 + }
1.111 + return retval;
1.112 +}
1.113 +
1.114 +
1.115 +//The clock_settime allow the calling process to set the value used by a
1.116 +//clock which is specified by clock_id
1.117 +EXPORT_C int clock_settime (clockid_t clock_id, const struct timespec *tp)
1.118 +{
1.119 + int retval = -1;
1.120 + TTime t(MAKE_TINT64 (0x00dcddb3 ,0x0f2f8000)) ; // 00:00, Jan 1st 1970
1.121 + TInt err;
1.122 + TInt64 microtime;
1.123 +
1.124 + if(tp == NULL)
1.125 + {
1.126 + errno = EFAULT;
1.127 + return retval;
1.128 + }
1.129 +
1.130 + //Check for boundary values of seconds and microseconds
1.131 + if (BOUNDARY_CHECK(tp))
1.132 + {
1.133 + errno = EINVAL;
1.134 + return retval;
1.135 + }
1.136 +
1.137 + switch(clock_id)
1.138 + {
1.139 + case CLOCK_REALTIME:
1.140 + //We support only the wall-clock,hence use the
1.141 + //User::SetHomeTime call to set the time
1.142 + t+=(TTimeIntervalSeconds)tp->tv_sec;
1.143 + microtime = (tp->tv_nsec)/1000;
1.144 + t+=(TTimeIntervalMicroSeconds)microtime;
1.145 + err = User::SetUTCTime(t);
1.146 + if(err)
1.147 + {
1.148 + MapError(err,errno);
1.149 + break;
1.150 + }
1.151 + else
1.152 + retval = 0;
1.153 + break;
1.154 +
1.155 + default:
1.156 + //For all other clocks that cannot be supported or invalid clockids,
1.157 + //we set errno to invalid
1.158 + retval = -1;
1.159 + errno = EINVAL;
1.160 + break;
1.161 + }
1.162 +
1.163 + return retval;
1.164 +}
1.165 +
1.166 +
1.167 +//Returns the clock ID of the CPU-time clock of the process specified by pid
1.168 +EXPORT_C int clock_getcpuclockid (pid_t pid, clockid_t *clock_id)
1.169 +{
1.170 + int retval = -1;
1.171 +
1.172 + if(clock_id == NULL)
1.173 + {
1.174 + errno = EFAULT;
1.175 + return retval;
1.176 + }
1.177 +
1.178 + /* We don't allow any process ID but our own. */
1.179 + if (pid == 0)
1.180 + {
1.181 + //The only available clock is the realtime wall clock
1.182 + //Hence we set the clockid to that
1.183 + *clock_id = CLOCK_REALTIME;
1.184 + retval = 0;
1.185 + }
1.186 + else
1.187 + errno = ESRCH;
1.188 +
1.189 + return retval;
1.190 +}
1.191 +
1.192 +
1.193 +//clock_nanosleep will not be interrupted by the signal emulation.
1.194 +//hence EINTR is not valid here.
1.195 +
1.196 +EXPORT_C int clock_nanosleep(clockid_t clock_id, int flags,
1.197 + const struct timespec *rqtp, struct timespec */*rmtp*/)
1.198 +{
1.199 + int retval = -1;
1.200 +
1.201 + if(rqtp == NULL)
1.202 + {
1.203 + errno = EFAULT;
1.204 + return retval;
1.205 + }
1.206 +
1.207 + //Check for boundary values of seconds and microseconds
1.208 + if (BOUNDARY_CHECK(rqtp))
1.209 + {
1.210 + errno = EINVAL;
1.211 + return retval;
1.212 + }
1.213 +
1.214 + switch(clock_id)
1.215 + {
1.216 + case CLOCK_REALTIME:
1.217 + {
1.218 + switch(flags)
1.219 + {
1.220 + case TIMER_ABSTIME:
1.221 + {
1.222 + TTime lSetTime(MAKE_TINT64 (0x00dcddb3 ,0x0f2f8000)) ; // 00:00, Jan 1st 1970
1.223 +
1.224 + lSetTime+=(TTimeIntervalSeconds)rqtp->tv_sec;
1.225 + lSetTime+=(TTimeIntervalMicroSeconds)(rqtp->tv_nsec/1000);
1.226 +
1.227 + User::At(lSetTime);
1.228 + }
1.229 + break;
1.230 +
1.231 + default:
1.232 + {
1.233 + unsigned long timeout;
1.234 + timeout = (1000000 * rqtp->tv_sec) + (rqtp->tv_nsec /1000);
1.235 + User::AfterHighRes(timeout);
1.236 + }
1.237 + break;
1.238 + }
1.239 + }
1.240 + retval = 0;
1.241 + break;
1.242 +
1.243 + default:
1.244 + //For all other clocks that cannot be supported or invalid clockids,
1.245 + //we set errno to invalid
1.246 + retval = -1;
1.247 + errno = EINVAL;
1.248 + break;
1.249 + }
1.250 +
1.251 + return retval;
1.252 +}
1.253 +} // extern "C"
1.254 +
1.255 +//EOF
1.256 +
1.257 +
1.258 +