sl@0: /* sl@0: * Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: * All rights reserved. sl@0: * This component and the accompanying materials are made available sl@0: * under the terms of "Eclipse Public License v1.0" sl@0: * which accompanies this distribution, and is available sl@0: * at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: * sl@0: * Initial Contributors: sl@0: * Nokia Corporation - initial contribution. sl@0: * sl@0: * Contributors: sl@0: * sl@0: * Description: This is a project specific source file for building the sl@0: * clock related functions as part of librt library. sl@0: * sl@0: */ sl@0: sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: #include "lposix.h" sl@0: sl@0: #define UNIX_BASE TTime(MAKE_TINT64(0x00dcddb3,0x0f2f8000)) // 00:00, Jan 1st 1970 sl@0: sl@0: #define BOUNDARY_CHECK(rqtp) ( (rqtp->tv_nsec != 0 && rqtp->tv_nsec < 1000) || \ sl@0: rqtp->tv_nsec >= 1000000000L )\ sl@0: sl@0: extern "C" { sl@0: sl@0: //Returns the resolution (granularity) of a clock sl@0: //This value is placed in a (non-NULL) *res sl@0: EXPORT_C int clock_getres(clockid_t clock_id, struct timespec* res) sl@0: { sl@0: int retval = -1; sl@0: //We expect the user of the library to give us a valid pointer sl@0: if(res == NULL) sl@0: { sl@0: return 0; //no strict reactions please. sl@0: } sl@0: sl@0: switch (clock_id) sl@0: { sl@0: case CLOCK_REALTIME: sl@0: //Since Symbian OS is not realtime,we simulate the same using sl@0: //the available wall clock whose resolution is upto microseconds sl@0: res->tv_sec = 0; sl@0: res->tv_nsec = 1000; sl@0: retval = 0; sl@0: break; sl@0: sl@0: default: sl@0: //For all other clocks that cannot be supported or invalid clockids, sl@0: //we set errno to not-supported sl@0: retval = -1; sl@0: errno = EINVAL; sl@0: break; sl@0: } sl@0: sl@0: return retval; sl@0: } sl@0: sl@0: //Allow the calling process to retrieve the value used by a clock which sl@0: //is specified by clock_id sl@0: EXPORT_C int clock_gettime (clockid_t clock_id, struct timespec *tp) sl@0: { sl@0: int retval = -1; sl@0: TTime t; sl@0: TTimeIntervalSeconds iSeconds; sl@0: TInt err; sl@0: //We expect the user of the library to give us a valid pointer sl@0: if(tp == NULL) sl@0: { sl@0: errno = EFAULT; sl@0: return retval; sl@0: } sl@0: sl@0: switch(clock_id) sl@0: { sl@0: case CLOCK_REALTIME: sl@0: //Since Symbian OS is not realtime,we simulate the same using sl@0: //the available wall clock.We use TTime::HomeTime() call to get sl@0: //the wall clock time sl@0: t.HomeTime(); sl@0: err = t.SecondsFrom(UNIX_BASE, iSeconds); //TODO check for the negative tests.. sl@0: if (!err) sl@0: { sl@0: t-=iSeconds;//extracting seconds info into iSeconds sl@0: tp->tv_sec = iSeconds.Int(); sl@0: tp->tv_nsec = t.Int64(); sl@0: retval = 0; sl@0: } sl@0: break; sl@0: sl@0: default: sl@0: //For all other clocks that cannot be supported or invalid clockids, sl@0: //we set errno to invalid sl@0: retval = -1; sl@0: errno = EINVAL; sl@0: break; sl@0: } sl@0: return retval; sl@0: } sl@0: sl@0: sl@0: //The clock_settime allow the calling process to set the value used by a sl@0: //clock which is specified by clock_id sl@0: EXPORT_C int clock_settime (clockid_t clock_id, const struct timespec *tp) sl@0: { sl@0: int retval = -1; sl@0: TTime t(MAKE_TINT64 (0x00dcddb3 ,0x0f2f8000)) ; // 00:00, Jan 1st 1970 sl@0: TInt err; sl@0: TInt64 microtime; sl@0: sl@0: if(tp == NULL) sl@0: { sl@0: errno = EFAULT; sl@0: return retval; sl@0: } sl@0: sl@0: //Check for boundary values of seconds and microseconds sl@0: if (BOUNDARY_CHECK(tp)) sl@0: { sl@0: errno = EINVAL; sl@0: return retval; sl@0: } sl@0: sl@0: switch(clock_id) sl@0: { sl@0: case CLOCK_REALTIME: sl@0: //We support only the wall-clock,hence use the sl@0: //User::SetHomeTime call to set the time sl@0: t+=(TTimeIntervalSeconds)tp->tv_sec; sl@0: microtime = (tp->tv_nsec)/1000; sl@0: t+=(TTimeIntervalMicroSeconds)microtime; sl@0: err = User::SetUTCTime(t); sl@0: if(err) sl@0: { sl@0: MapError(err,errno); sl@0: break; sl@0: } sl@0: else sl@0: retval = 0; sl@0: break; sl@0: sl@0: default: sl@0: //For all other clocks that cannot be supported or invalid clockids, sl@0: //we set errno to invalid sl@0: retval = -1; sl@0: errno = EINVAL; sl@0: break; sl@0: } sl@0: sl@0: return retval; sl@0: } sl@0: sl@0: sl@0: //Returns the clock ID of the CPU-time clock of the process specified by pid sl@0: EXPORT_C int clock_getcpuclockid (pid_t pid, clockid_t *clock_id) sl@0: { sl@0: int retval = -1; sl@0: sl@0: if(clock_id == NULL) sl@0: { sl@0: errno = EFAULT; sl@0: return retval; sl@0: } sl@0: sl@0: /* We don't allow any process ID but our own. */ sl@0: if (pid == 0) sl@0: { sl@0: //The only available clock is the realtime wall clock sl@0: //Hence we set the clockid to that sl@0: *clock_id = CLOCK_REALTIME; sl@0: retval = 0; sl@0: } sl@0: else sl@0: errno = ESRCH; sl@0: sl@0: return retval; sl@0: } sl@0: sl@0: sl@0: //clock_nanosleep will not be interrupted by the signal emulation. sl@0: //hence EINTR is not valid here. sl@0: sl@0: EXPORT_C int clock_nanosleep(clockid_t clock_id, int flags, sl@0: const struct timespec *rqtp, struct timespec */*rmtp*/) sl@0: { sl@0: int retval = -1; sl@0: sl@0: if(rqtp == NULL) sl@0: { sl@0: errno = EFAULT; sl@0: return retval; sl@0: } sl@0: sl@0: //Check for boundary values of seconds and microseconds sl@0: if (BOUNDARY_CHECK(rqtp)) sl@0: { sl@0: errno = EINVAL; sl@0: return retval; sl@0: } sl@0: sl@0: switch(clock_id) sl@0: { sl@0: case CLOCK_REALTIME: sl@0: { sl@0: switch(flags) sl@0: { sl@0: case TIMER_ABSTIME: sl@0: { sl@0: TTime lSetTime(MAKE_TINT64 (0x00dcddb3 ,0x0f2f8000)) ; // 00:00, Jan 1st 1970 sl@0: sl@0: lSetTime+=(TTimeIntervalSeconds)rqtp->tv_sec; sl@0: lSetTime+=(TTimeIntervalMicroSeconds)(rqtp->tv_nsec/1000); sl@0: sl@0: User::At(lSetTime); sl@0: } sl@0: break; sl@0: sl@0: default: sl@0: { sl@0: unsigned long timeout; sl@0: timeout = (1000000 * rqtp->tv_sec) + (rqtp->tv_nsec /1000); sl@0: User::AfterHighRes(timeout); sl@0: } sl@0: break; sl@0: } sl@0: } sl@0: retval = 0; sl@0: break; sl@0: sl@0: default: sl@0: //For all other clocks that cannot be supported or invalid clockids, sl@0: //we set errno to invalid sl@0: retval = -1; sl@0: errno = EINVAL; sl@0: break; sl@0: } sl@0: sl@0: return retval; sl@0: } sl@0: } // extern "C" sl@0: sl@0: //EOF sl@0: sl@0: sl@0: