genericopenlibs/openenvcore/libc/src/clock_funcs.cpp
changeset 0 e4d67989cc36
child 18 47c74d1534e1
child 54 4332f0f7be53
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 /*
       
     2 * Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  This is a project specific include file for building the 
       
    15 *                clock related functions as part of libc library.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 #include <time.h>
       
    21 #include <errno.h>
       
    22 #include <pthread.h>
       
    23 #include <stdlib.h>
       
    24 #include <e32std.h>
       
    25 #include <sys/_timeval.h>
       
    26 #include <sys/types.h>
       
    27 #include "lposix.h"
       
    28 
       
    29 #define UNIX_BASE	TTime(MAKE_TINT64(0x00dcddb3,0x0f2f8000))    // 00:00, Jan 1st 1970
       
    30 
       
    31 extern "C" {
       
    32 
       
    33 //Returns the resolution (granularity) of a clock
       
    34 //This value is placed in a (non-NULL) *res
       
    35 EXPORT_C int clock_getres(clockid_t clock_id, struct timespec* res)
       
    36 {
       
    37 	int retval = -1;
       
    38 	//We expect the user of the library to give us a valid pointer	
       
    39 	if(res == NULL)
       
    40 	{
       
    41 		errno = EFAULT;
       
    42 		return retval;
       
    43 	}
       
    44 			
       
    45 	switch (clock_id) 
       
    46 	{
       
    47 		case CLOCK_REALTIME:
       
    48 			//Since Symbian OS is not realtime,we simulate the same using
       
    49 			//the available wall clock whose resolution is upto microseconds
       
    50 			res->tv_sec = 0;
       
    51 			res->tv_nsec = 1000000;
       
    52 			retval = 0;
       
    53 			break;
       
    54 		
       
    55 		default:
       
    56 			//For all other clocks that cannot be supported or invalid clockids,
       
    57 			//we set errno to not-supported
       
    58 			retval = -1;
       
    59 			errno = EINVAL;
       
    60 			break;
       
    61 	}
       
    62 	return retval;
       
    63 }
       
    64 
       
    65 //Allow the calling process to retrieve the value used by a clock which 
       
    66 //is specified by clock_id
       
    67 EXPORT_C int clock_gettime (clockid_t clock_id, struct timespec *tp)
       
    68 {
       
    69 	int retval = -1;
       
    70 	TTime t;
       
    71 	TTimeIntervalSeconds iSeconds;
       
    72 	TInt err;
       
    73 	//We expect the user of the library to give us a valid pointer	
       
    74 	if(tp == NULL)
       
    75 	{
       
    76 		errno = EFAULT;
       
    77 		return retval;
       
    78 	}
       
    79 
       
    80 	switch(clock_id)
       
    81 	{
       
    82 		case CLOCK_REALTIME:
       
    83 			//Since Symbian OS is not realtime,we simulate the same using
       
    84 			//the available wall clock.We use TTime::HomeTime() call to get
       
    85 			//the wall clock time
       
    86 			t.HomeTime();
       
    87 			err = t.SecondsFrom(UNIX_BASE, iSeconds);
       
    88 			t-=iSeconds;//extracting seconds info into iSeconds
       
    89 			if (!err)
       
    90 			{
       
    91 				tp->tv_sec = iSeconds.Int();
       
    92 				tp->tv_nsec = t.Int64();
       
    93 				retval = 0;
       
    94 			}
       
    95 			break;
       
    96 		
       
    97 		default:
       
    98 			//For all other clocks that cannot be supported or invalid clockids,
       
    99 			//we set errno to invalid
       
   100 			retval = -1;
       
   101 			errno = EINVAL;
       
   102 			break;
       
   103 	}
       
   104 	return retval;
       
   105 }
       
   106 
       
   107 
       
   108 //The clock_settime allow the calling process to set the value used by a 
       
   109 //clock which is specified by  clock_id
       
   110 EXPORT_C int clock_settime (clockid_t clock_id, const struct timespec *tp)
       
   111 {
       
   112 	int retval = -1;
       
   113 	TTime t(MAKE_TINT64 (0x00dcddb3 ,0x0f2f8000)) ;  // 00:00, Jan 1st 1970
       
   114 	TInt err;
       
   115 	TInt64 microtime;
       
   116 	//We must get a filled structure from the user of the library
       
   117 	if(tp == NULL)
       
   118 	{
       
   119 		errno = EFAULT;
       
   120 		return retval;
       
   121 	}
       
   122 	//Check for boundary values of seconds and microseconds
       
   123 	if (tp->tv_nsec < 0 || tp->tv_nsec >= 1000000000L) 
       
   124 	{
       
   125 		errno = ERANGE;
       
   126 		return retval;
       
   127 	}
       
   128 
       
   129 	switch(clock_id)
       
   130 	{
       
   131 		case CLOCK_REALTIME:
       
   132 			//We support only the wall-clock,hence use the 
       
   133 			//User::SetHomeTime call to set the time
       
   134 			t+=(TTimeIntervalSeconds)tp->tv_sec;
       
   135 			microtime = (tp->tv_nsec)/1000;
       
   136 			t+=(TTimeIntervalMicroSeconds)microtime;        
       
   137 			err = User::SetUTCTime(t);
       
   138 			if(err)
       
   139 			{
       
   140 				MapError(err,errno);
       
   141 				break;
       
   142 			}
       
   143 			else
       
   144 				retval = 0;
       
   145 			break;
       
   146 			
       
   147 		default:
       
   148 			//For all other clocks that cannot be supported or invalid clockids,
       
   149 			//we set errno to invalid
       
   150 			retval = -1;
       
   151 			errno = EINVAL;
       
   152 			break;
       
   153 	}
       
   154 	return retval;
       
   155 }
       
   156 
       
   157 
       
   158 //Returns the clock ID of the CPU-time clock of the process specified by pid
       
   159 EXPORT_C int clock_getcpuclockid (pid_t pid, clockid_t *clock_id)
       
   160 {
       
   161 	int retval = -1;
       
   162 	/* We don't allow any process ID but our own.  */
       
   163 	if (pid == 0)
       
   164 	{
       
   165 		//The only available clock is the realtime wall clock
       
   166 		//Hence we set the clockid to that
       
   167 		*clock_id = CLOCK_REALTIME;
       
   168 		retval = 0;
       
   169 	}
       
   170 	else
       
   171 		errno = ESRCH;
       
   172 	
       
   173 	return retval;
       
   174 }
       
   175 
       
   176 //Makes small adjustments to the system time,
       
   177 //advancing it by the time specified by the timeval delta
       
   178 EXPORT_C int adjtime(const struct timeval *delta, struct timeval *olddelta)
       
   179 {
       
   180 	//We can make only positive adjutments to the available clock
       
   181 	//The synchronization to the global time server is provided to us
       
   182 	//by the User::SetHomeTime api itself
       
   183 	int retval = -1;
       
   184 	TTime t;
       
   185 	TInt err;
       
   186 	TInt64 microtime;
       
   187 	long secs = 0;
       
   188 	suseconds_t usec = 0;
       
   189 	
       
   190 	//We expect the user of the library to give us a valid pointer		
       
   191 	if(delta == NULL)
       
   192 	{
       
   193 		errno = EFAULT;
       
   194 		return retval;
       
   195 	}
       
   196 		
       
   197 	if ((delta->tv_usec) > 1000000) 
       
   198 	{
       
   199 		errno = ERANGE;
       
   200 		return retval;
       
   201 	}
       
   202 	//Check for negative of seconds and make it positive
       
   203 	if((delta->tv_sec) < 0)
       
   204 		secs = -1*(delta->tv_sec);
       
   205 	else
       
   206 		secs = delta->tv_sec;
       
   207 
       
   208 	//Check for negative of microseconds and make it positive
       
   209 	if((delta->tv_usec) < 0)
       
   210 		usec = -1*(delta->tv_usec);
       
   211 	else
       
   212 		usec = delta->tv_usec;
       
   213 
       
   214 	t.HomeTime();
       
   215 	t+=(TTimeIntervalSeconds)secs;
       
   216 	microtime = usec;
       
   217 	t+=(TTimeIntervalMicroSeconds)microtime;        
       
   218 	err = User::SetHomeTime(t);
       
   219 	if (!err)
       
   220 	{
       
   221 		retval = 0;
       
   222 	  	//olddelta is always zero in case of success
       
   223 		olddelta->tv_sec = 0;
       
   224 		olddelta->tv_usec = 0;
       
   225 	}
       
   226 	else
       
   227 	{
       
   228 		MapError(err,errno);
       
   229 		retval = -1;
       
   230 	}
       
   231 	return retval;
       
   232 }
       
   233 
       
   234 } // extern "C"