os/ossrv/genericopenlibs/posixrealtimeextensions/src/timer.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// Name        : timer.cpp
sl@0
    15
// Part of     : librt-timer specific cpp file
sl@0
    16
// This is a project specific source file for building the 
sl@0
    17
// timer related functions as part of librt library.
sl@0
    18
// 
sl@0
    19
//
sl@0
    20
sl@0
    21
#include <e32math.h> 
sl@0
    22
sl@0
    23
#include "sysif.h"
sl@0
    24
#include "timer.h"
sl@0
    25
#include "timerhandler.h"
sl@0
    26
#include "timermessage.h"
sl@0
    27
sl@0
    28
#define BOUNDARY_CHECK(rqtp) ((rqtp.tv_nsec != 0 && rqtp.tv_nsec < 1000) || \
sl@0
    29
							   rqtp.tv_nsec >= 1000000000L )\
sl@0
    30
sl@0
    31
//ctor
sl@0
    32
static TInt64 seed = 0xdeadbeef;
sl@0
    33
CRtTimer::CRtTimer(struct sigevent *aSig)
sl@0
    34
	{
sl@0
    35
	iTimer.Set(this);
sl@0
    36
	iTimerId = Math::Rand (seed);
sl@0
    37
	
sl@0
    38
	if(aSig == NULL)	
sl@0
    39
		{
sl@0
    40
		iSigEvent.sigev_notify = SIGEV_SIGNAL;
sl@0
    41
		iSigEvent.sigev_signo = SIGALRM;
sl@0
    42
		}
sl@0
    43
	else
sl@0
    44
		{
sl@0
    45
		iSigEvent = *aSig;				
sl@0
    46
		}
sl@0
    47
		
sl@0
    48
	iIsArmed = EFalse;
sl@0
    49
	}
sl@0
    50
sl@0
    51
//dtor
sl@0
    52
CRtTimer::~CRtTimer()
sl@0
    53
	{
sl@0
    54
	//should be called in context of the timer server thread.
sl@0
    55
	if(iIsArmed)
sl@0
    56
		{
sl@0
    57
		iTimer.Cancel();	
sl@0
    58
		}	
sl@0
    59
	}
sl@0
    60
sl@0
    61
//NewL method
sl@0
    62
CRtTimer* CRtTimer::New(struct sigevent *aSig)
sl@0
    63
	{
sl@0
    64
	return new CRtTimer(aSig);
sl@0
    65
	}
sl@0
    66
sl@0
    67
//sets the timer for the given value
sl@0
    68
TInt CRtTimer::SetTime(TInt aFlag, const struct itimerspec *aIpTime,
sl@0
    69
			 struct itimerspec *aOpTime)
sl@0
    70
	{
sl@0
    71
	//Check for boundary values of seconds and microseconds
sl@0
    72
	if (aIpTime == NULL || ((BOUNDARY_CHECK(aIpTime->it_value) || BOUNDARY_CHECK(aIpTime->it_interval)) &&
sl@0
    73
	   (aIpTime->it_value.tv_sec != 0 || aIpTime->it_value.tv_nsec != 0)) )
sl@0
    74
		{
sl@0
    75
		return KErrArgument;
sl@0
    76
		}
sl@0
    77
		
sl@0
    78
	if(aIpTime->it_value.tv_sec == 0 && aIpTime->it_value.tv_nsec == 0)
sl@0
    79
		{
sl@0
    80
		if(!iIsArmed)	
sl@0
    81
			return KErrNone;
sl@0
    82
		else
sl@0
    83
			iIsTimerReset = ETrue;
sl@0
    84
		}
sl@0
    85
sl@0
    86
	//load the time to expiration in the output timer value.	
sl@0
    87
	if(aOpTime)
sl@0
    88
		{
sl@0
    89
		Time(aOpTime);	
sl@0
    90
		}
sl@0
    91
sl@0
    92
	//start setting the timer value...
sl@0
    93
	clock_gettime(CLOCK_REALTIME, &iStartTime.it_value);
sl@0
    94
	
sl@0
    95
	iStartTime.it_interval = aIpTime->it_interval;		
sl@0
    96
	iEndTime = aIpTime->it_value;
sl@0
    97
	
sl@0
    98
	if((aFlag & TIMER_ABSTIME) == 0) // relative timer
sl@0
    99
		{
sl@0
   100
		iEndTime.tv_sec+=iStartTime.it_value.tv_sec;
sl@0
   101
		iEndTime.tv_nsec+=iStartTime.it_value.tv_nsec;
sl@0
   102
		}
sl@0
   103
	getTimerHandler()->session.OnDemandConnect(getTimerHandler()->iServer);
sl@0
   104
	TInt lRet = getTimerHandler()->session.SetTime(iTimerId);
sl@0
   105
	return lRet;
sl@0
   106
	}
sl@0
   107
sl@0
   108
//gets the time to expiry.
sl@0
   109
TInt CRtTimer::Time(struct itimerspec *aTime) const
sl@0
   110
	{
sl@0
   111
	TInt err = KErrNone;
sl@0
   112
	if(NULL == aTime)
sl@0
   113
		{
sl@0
   114
		err = KErrArgument;	
sl@0
   115
		}
sl@0
   116
	else if (!iIsArmed)
sl@0
   117
		{
sl@0
   118
		memset(aTime, 0, sizeof(struct itimerspec));
sl@0
   119
		}
sl@0
   120
	else
sl@0
   121
		{
sl@0
   122
		struct timespec clktime;
sl@0
   123
		clock_gettime(CLOCK_REALTIME, &clktime);
sl@0
   124
		
sl@0
   125
		aTime->it_value.tv_sec = iEndTime.tv_sec - clktime.tv_sec;
sl@0
   126
		aTime->it_value.tv_nsec = iEndTime.tv_nsec - clktime.tv_nsec;	
sl@0
   127
		aTime->it_interval = iStartTime.it_interval;				
sl@0
   128
		}	
sl@0
   129
		
sl@0
   130
	return err;	
sl@0
   131
	}
sl@0
   132
sl@0
   133
//gets the overruns for this timer
sl@0
   134
TInt CRtTimer::OverrunCount(TInt& aOverrunCount) const
sl@0
   135
	{
sl@0
   136
#if (!defined SYMBIAN_OE_POSIX_SIGNALS || !defined SYMBIAN_OE_LIBRT)
sl@0
   137
	aOverrunCount = aOverrunCount;//warning fix
sl@0
   138
	return KErrNotSupported;	
sl@0
   139
sl@0
   140
#else
sl@0
   141
	aOverrunCount = Backend()->Overrun(iTimerId);
sl@0
   142
	if(aOverrunCount >= DELAYTIMER_MAX)
sl@0
   143
		aOverrunCount = DELAYTIMER_MAX;
sl@0
   144
	
sl@0
   145
	return KErrNone;
sl@0
   146
#endif
sl@0
   147
	}
sl@0
   148
//EOF
sl@0
   149