diff options
author | Erlang/OTP <[email protected]> | 2009-11-20 14:54:40 +0000 |
---|---|---|
committer | Erlang/OTP <[email protected]> | 2009-11-20 14:54:40 +0000 |
commit | 84adefa331c4159d432d22840663c38f155cd4c1 (patch) | |
tree | bff9a9c66adda4df2106dfd0e5c053ab182a12bd /lib/cosTime/src | |
download | otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.gz otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.bz2 otp-84adefa331c4159d432d22840663c38f155cd4c1.zip |
The R13B03 release.OTP_R13B03
Diffstat (limited to 'lib/cosTime/src')
-rw-r--r-- | lib/cosTime/src/CosTime.cfg | 6 | ||||
-rw-r--r-- | lib/cosTime/src/CosTime.idl | 59 | ||||
-rw-r--r-- | lib/cosTime/src/CosTime_TIO_impl.erl | 200 | ||||
-rw-r--r-- | lib/cosTime/src/CosTime_TimeService_impl.erl | 180 | ||||
-rw-r--r-- | lib/cosTime/src/CosTime_UTO_impl.erl | 241 | ||||
-rw-r--r-- | lib/cosTime/src/CosTimerEvent.cfg | 4 | ||||
-rw-r--r-- | lib/cosTime/src/CosTimerEvent.idl | 45 | ||||
-rw-r--r-- | lib/cosTime/src/CosTimerEvent_TimerEventHandler_impl.erl | 304 | ||||
-rw-r--r-- | lib/cosTime/src/CosTimerEvent_TimerEventService_impl.erl | 118 | ||||
-rw-r--r-- | lib/cosTime/src/Makefile | 205 | ||||
-rw-r--r-- | lib/cosTime/src/TimeBase.idl | 22 | ||||
-rw-r--r-- | lib/cosTime/src/cosTime.app.src | 30 | ||||
-rw-r--r-- | lib/cosTime/src/cosTime.appup.src | 6 | ||||
-rw-r--r-- | lib/cosTime/src/cosTime.erl | 321 | ||||
-rw-r--r-- | lib/cosTime/src/cosTimeApp.hrl | 76 |
15 files changed, 1817 insertions, 0 deletions
diff --git a/lib/cosTime/src/CosTime.cfg b/lib/cosTime/src/CosTime.cfg new file mode 100644 index 0000000000..1aad9ebb94 --- /dev/null +++ b/lib/cosTime/src/CosTime.cfg @@ -0,0 +1,6 @@ +{this, "CosTime::UTO"}. +{{handle_info, "CosTime::UTO"}, true}. +{this, "CosTime::TIO"}. +{{handle_info, "CosTime::TIO"}, true}. +{this, "CosTime::TimeService"}. +{{handle_info, "CosTime::TimeService"}, true}. diff --git a/lib/cosTime/src/CosTime.idl b/lib/cosTime/src/CosTime.idl new file mode 100644 index 0000000000..2bf32681c1 --- /dev/null +++ b/lib/cosTime/src/CosTime.idl @@ -0,0 +1,59 @@ +#ifndef _COS_TIME_IDL_ +#define _COS_TIME_IDL_ + +#pragma prefix "omg.org" + +#include<TimeBase.idl> + +module CosTime { + enum TimeComparison { + TCEqualTo, + TCLessThan, + TCGreaterThan, + TCIndeterminate + }; + enum ComparisonType{ + IntervalC, + MidC }; + enum OverlapType { + OTContainer, + OTContained, + OTOverlap, + OTNoOverlap + }; + + exception TimeUnavailable {}; + interface TIO; // forward declaration + + interface UTO { + readonly attribute TimeBase::TimeT time; + readonly attribute TimeBase::InaccuracyT inaccuracy; + readonly attribute TimeBase::TdfT tdf; + readonly attribute TimeBase::UtcT utc_time; + + UTO absolute_time(); + TimeComparison compare_time( in ComparisonType comparison_type, in UTO uto ); + TIO time_to_interval( in UTO uto ); + TIO interval(); + }; + + interface TIO { + readonly attribute TimeBase::IntervalT time_interval; + + OverlapType spans ( in UTO time, out TIO overlap ); + OverlapType overlaps ( in TIO interval, out TIO overlap ); + UTO time (); + }; + + interface TimeService { + UTO universal_time() + raises(TimeUnavailable ); + UTO secure_universal_time() + raises(TimeUnavailable ); + UTO new_universal_time( in TimeBase::TimeT time, in TimeBase::InaccuracyT inaccuracy, in TimeBase::TdfT tdf ); + UTO uto_from_utc( in TimeBase::UtcT utc ); + TIO new_interval( in TimeBase::TimeT lower, in TimeBase::TimeT upper ); + }; +}; + +#endif diff --git a/lib/cosTime/src/CosTime_TIO_impl.erl b/lib/cosTime/src/CosTime_TIO_impl.erl new file mode 100644 index 0000000000..d6d4ee894b --- /dev/null +++ b/lib/cosTime/src/CosTime_TIO_impl.erl @@ -0,0 +1,200 @@ +%%-------------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2000-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%---------------------------------------------------------------------- +%% File : CosTime_TIO_impl.erl +%% Purpose : +%%---------------------------------------------------------------------- + +-module('CosTime_TIO_impl'). + +%%--------------- INCLUDES ----------------------------------- +-include("cosTimeApp.hrl"). + +%%--------------- EXPORTS ------------------------------------ +%%--------------- External ----------------------------------- +%% Attributes (external) +-export(['_get_time_interval'/2]). + +%% Interface functions +-export([spans/3, overlaps/3, time/2]). + +%%--------------- gen_server specific exports ---------------- +-export([handle_info/2, code_change/3]). +-export([init/1, terminate/2]). + + +%% Data structures +-record(state, {interval, + tdf, + timer}). +%% Data structures constructors +-define(get_InitState(I,T,TO), + #state{interval = I, + tdf = T, + timer = TO}). + +%% Data structures selectors +-define(get_IntervalT(S), S#state.interval). +-define(get_Lower(S), (S#state.interval)#'TimeBase_IntervalT'.lower_bound). +-define(get_Upper(S), (S#state.interval)#'TimeBase_IntervalT'.upper_bound). +-define(get_Tdf(S), S#state.tdf). +-define(get_TimerObj(S), S#state.timer). + +%%-----------------------------------------------------------% +%% function : handle_info, code_change +%% Arguments: +%% Returns : +%% Effect : Functions demanded by the gen_server module. +%%------------------------------------------------------------ + +code_change(_OldVsn, State, _Extra) -> + {ok, State}. +handle_info(_Info, State) -> + {noreply, State}. + +%%----------------------------------------------------------% +%% function : init, terminate +%% Arguments: +%%----------------------------------------------------------- + +init([Interval, Tdf, Timer]) -> + {ok, ?get_InitState(Interval, Tdf, Timer)}. + +terminate(_Reason, _State) -> + ok. + +%%----------------------------------------------------------- +%%------------------------ attributes ----------------------- +%%----------------------------------------------------------- +%%----------------------------------------------------------% +%% Attribute: '_get_time_interval' +%% Type : readonly +%% Returns : +%%----------------------------------------------------------- +'_get_time_interval'(_OE_THIS, State) -> + {reply, ?get_IntervalT(State), State}. + +%%----------------------------------------------------------- +%%------- Exported external functions ----------------------- +%%----------------------------------------------------------- +%%----------------------------------------------------------% +%% function : spans +%% Arguments: Time - UTO +%% Returns : CosTime::OverLapType - enum() +%% TIO - out-parameter. +%%----------------------------------------------------------- +spans(_OE_THIS, State, Time) -> + ?time_TypeCheck(Time, 'CosTime_UTO'), + case catch 'CosTime_UTO':'_get_utc_time'(Time) of + #'TimeBase_UtcT'{time = Btime, inacclo = InaccL, inacchi=InaccH} -> + Inaccuarcy = ?concat_TimeT(InaccH, InaccL), + BL = Btime - Inaccuarcy, + BU = Btime + Inaccuarcy, + L = ?get_Lower(State), + U = ?get_Upper(State), + {Type, NewL, NewU} = + if + L=<BL, U>=BU -> + {'OTContainer',BL,BU}; + L>=BL, U=<BU -> + {'OTContained',L,U}; + L<BL, U=<BU, U>=BL -> + {'OTOverlap',BL,U}; + L>=BL, L=<BU, U>BU -> + {'OTOverlap',L,BU}; + L>BU -> + {'OTNoOverlap',BU,L}; + true -> + {'OTNoOverlap',U,BL} + end, + {reply, + {Type, + 'CosTime_TIO':oe_create([#'TimeBase_IntervalT'{lower_bound=NewL, + upper_bound=NewU}, + ?get_Tdf(State), + ?get_TimerObj(State)], + [{pseudo,true}|?CREATE_OPTS])}, + State}; + _ -> + corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}) + end. + + +%%----------------------------------------------------------% +%% function : overlaps +%% Arguments: Interval - TIO +%% Returns : CosTime::OverLapType - enum() +%% TIO - out-parameter. +%%----------------------------------------------------------- +overlaps(_OE_THIS, State, Interval) -> + ?time_TypeCheck(Interval, 'CosTime_TIO'), + case catch 'CosTime_TIO':'_get_time_interval'(Interval) of + #'TimeBase_IntervalT'{lower_bound=BL, upper_bound=BU} -> + L = ?get_Lower(State), + U = ?get_Upper(State), + {Type, NewL, NewU} = + if + L=<BL, U>=BU -> + {'OTContainer',BL,BU}; + L>=BL, U=<BU -> + {'OTContained',L,U}; + L<BL, U=<BU, U>=BL -> + {'OTOverlap',BL,U}; + L>=BL, L=<BU, U>BU -> + {'OTOverlap',L,BU}; + L>BU -> + {'OTNoOverlap',BU,L}; + true -> + {'OTNoOverlap',U,BL} + end, + {reply, + {Type, + 'CosTime_TIO':oe_create([#'TimeBase_IntervalT'{lower_bound=NewL, + upper_bound=NewU}, + ?get_Tdf(State), + ?get_TimerObj(State)], + [{pseudo,true}|?CREATE_OPTS])}, + State}; + _ -> + corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}) + end. + +%%----------------------------------------------------------% +%% function : time +%% Arguments: - +%% Returns : UTO +%%----------------------------------------------------------- +time(_OE_THIS, State) -> + L = ?get_Lower(State), + H = ?get_Upper(State), + Utc = #'TimeBase_UtcT'{time=(erlang:trunc(((H-L)/2))+L), + inacclo=L, + inacchi=H, + tdf=?get_Tdf(State)}, + {reply, + 'CosTime_UTO':oe_create([Utc, ?get_TimerObj(State)], [{pseudo,true}|?CREATE_OPTS]), + State}. + + +%%--------------- LOCAL FUNCTIONS ---------------------------- + +%%--------------- MISC FUNCTIONS, E.G. DEBUGGING ------------- +%%--------------- END OF MODULE ------------------------------ diff --git a/lib/cosTime/src/CosTime_TimeService_impl.erl b/lib/cosTime/src/CosTime_TimeService_impl.erl new file mode 100644 index 0000000000..bac4ae087c --- /dev/null +++ b/lib/cosTime/src/CosTime_TimeService_impl.erl @@ -0,0 +1,180 @@ +%%-------------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2000-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%---------------------------------------------------------------------- +%% File : CosTime_TimeService_impl.erl +%% Purpose : +%%---------------------------------------------------------------------- + +-module('CosTime_TimeService_impl'). + +%%--------------- INCLUDES ----------------------------------- +-include("cosTimeApp.hrl"). + +%%--------------- EXPORTS ------------------------------------ +%%--------------- External ----------------------------------- +%% Interface functions +-export([universal_time/2, secure_universal_time/2, new_universal_time/5]). +-export([uto_from_utc/3, new_interval/4]). + +%%--------------- gen_server specific exports ---------------- +-export([handle_info/2, code_change/3]). +-export([init/1, terminate/2]). + + +%% Data structures +-record(state, + {tdf, + inaccuracy}). +%% Data structures constructors +-define(get_InitState(T,I), + #state{tdf = T, + inaccuracy = I}). + +%% Data structures selectors +-define(get_Inaccuracy(S), S#state.inaccuracy). +-define(get_Tdf(S), S#state.tdf). + +%% Data structures modifiers + +%% MISC + +%%-----------------------------------------------------------% +%% function : handle_info, code_change +%% Arguments: +%% Returns : +%% Effect : Functions demanded by the gen_server module. +%%------------------------------------------------------------ + +code_change(_OldVsn, State, _Extra) -> + {ok, State}. + +handle_info(_Info, State) -> + ?debug_print("INFO: ~p~n", [_Info]), + {noreply, State}. + +%%----------------------------------------------------------% +%% function : init, terminate +%% Arguments: +%%----------------------------------------------------------- + +init([Tdf, Inaccuracy]) -> + process_flag(trap_exit, true), + {ok, ?get_InitState(Tdf, Inaccuracy)}. + +terminate(_Reason, _State) -> + ok. + +%%----------------------------------------------------------- +%%------- Exported external functions ----------------------- +%%----------------------------------------------------------- +%%----------------------------------------------------------% +%% function : universal_time +%% Arguments: - +%% Returns : CosTime::UTO | +%% {'EXCEPTION", #'CosTime_TimeUnavailable'{}} +%% NOTE : cosTime:create_universal_time will raise the correct +%% exception. +%%----------------------------------------------------------- +universal_time(OE_THIS, State) -> + {ok, Time} = create_universal_time(), + Inaccuracy = ?get_Inaccuracy(State), + Utc = #'TimeBase_UtcT'{time=Time, inacclo = ?low_TimeT(Inaccuracy), + inacchi = ?high_TimeT(Inaccuracy), + tdf = ?get_Tdf(State)}, + {reply, 'CosTime_UTO':oe_create([Utc, OE_THIS], [{pseudo,true}|?CREATE_OPTS]), State}. + +%%----------------------------------------------------------% +%% function : secure_universal_time +%% Arguments: +%% Returns : {'EXCEPTION", #'CosTime_TimeUnavailable'{}} +%%----------------------------------------------------------- +secure_universal_time(_OE_THIS, _State) -> + corba:raise(#'CosTime_TimeUnavailable'{}). + +%%----------------------------------------------------------% +%% function : new_universal_time +%% Arguments: Time - TimeBase::TimeT +%% Inaccuracy - TimeBase::InaccuracyT inaccuracy +%% Tdf - TimeBase::TdfT +%% Returns : CosTime::UTO +%%----------------------------------------------------------- +new_universal_time(OE_THIS, State, Time, Inaccuracy, Tdf) when + is_integer(Time) andalso is_integer(Inaccuracy) andalso is_integer(Tdf) andalso + Tdf=<12 andalso Inaccuracy=<?max_Inaccuracy andalso Time=<?max_TimeT -> + Utc = #'TimeBase_UtcT'{time=Time, inacclo = ?low_TimeT(Inaccuracy), + inacchi = ?high_TimeT(Inaccuracy), tdf = Tdf}, + {reply, 'CosTime_UTO':oe_create([Utc, OE_THIS], [{pseudo,true}|?CREATE_OPTS]), State}; +new_universal_time(_, _, _, _, _) -> + corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}). + +%%----------------------------------------------------------% +%% function : uto_from_utc +%% Arguments: Utc - TimeBase::UtcT +%% Returns : CosTime::UTO +%%----------------------------------------------------------- +uto_from_utc(OE_THIS, State, Utc) when is_record(Utc, 'TimeBase_UtcT') -> + {reply, 'CosTime_UTO':oe_create([Utc, OE_THIS],[{pseudo,true}|?CREATE_OPTS]),State}; +uto_from_utc(_, _, _) -> + corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}). + +%%----------------------------------------------------------% +%% function : new_interval +%% Arguments: Lower - TimeBase::TimeT +%% Upper - TimeBase::TimeT +%% Returns : CosTime::TIO +%%----------------------------------------------------------- +new_interval(OE_THIS, State, Lower, Upper) when is_integer(Lower) andalso is_integer(Upper) andalso + Lower=<Upper -> + {reply, 'CosTime_TIO':oe_create([#'TimeBase_IntervalT'{lower_bound=Lower, + upper_bound=Upper}, + ?get_Tdf(State), + OE_THIS], + [{pseudo,true}|?CREATE_OPTS]), State}; +new_interval(_, _, _, _) -> + corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}). + + +%%--------------- LOCAL FUNCTIONS ---------------------------- +%%-----------------------------------------------------------% +%% function : create_universal_utc +%% Arguments: - +%% Returns : TimeT or raises exception. +%% Effect : Creates a universal time; if time unavailable we +%% must raise CosTime_TimeUnavailable. +%% NOTE : 'datetime_to_gregorian_seconds' use year 0 as time +%% base. We want to use 15 october 1582, 00:00 as base. +%%------------------------------------------------------------ + +create_universal_time() -> + %% Time is supposed to be #100 nano-secs passed. + %% We add micro secs for a greater precision. + {MS,S,US} = now(), + case catch calendar:datetime_to_gregorian_seconds( + calendar:now_to_universal_time({MS,S,US})) of + Secs when is_integer(Secs) -> + {ok, (Secs-?ABSOLUTE_TIME_DIFF)*10000000 + US*10}; + _ -> + corba:raise(#'CosTime_TimeUnavailable'{}) + end. + +%%--------------- MISC FUNCTIONS, E.G. DEBUGGING ------------- +%%--------------- END OF MODULE ------------------------------ + diff --git a/lib/cosTime/src/CosTime_UTO_impl.erl b/lib/cosTime/src/CosTime_UTO_impl.erl new file mode 100644 index 0000000000..b35e215e90 --- /dev/null +++ b/lib/cosTime/src/CosTime_UTO_impl.erl @@ -0,0 +1,241 @@ +%%-------------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2000-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%---------------------------------------------------------------------- +%% File : CosTime_UTO_impl.erl +%% Purpose : +%%---------------------------------------------------------------------- + +-module('CosTime_UTO_impl'). + +%%--------------- INCLUDES ----------------------------------- +-include("cosTimeApp.hrl"). + + +%%--------------- EXPORTS ------------------------------------ +%%--------------- External ----------------------------------- +%% Attributes (external) +-export(['_get_time'/2, + '_get_inaccuracy'/2, + '_get_tdf'/2, + '_get_utc_time'/2]). + +%% Interface functions +-export([absolute_time/2, compare_time/4]). +-export([time_to_interval/3, interval/2]). + +%%--------------- gen_server specific exports ---------------- +-export([handle_info/2, code_change/3]). +-export([init/1, terminate/2]). + + +%% Data structures +-record(state, {timer, utc}). +%% Data structures constructors +-define(get_InitState(U, T), #state{timer = T, utc = U}). + +%% Data structures selectors +-define(get_Time(S), (S#state.utc)#'TimeBase_UtcT'.time). +-define(get_Inaccuracy(S), ?concat_TimeT((S#state.utc)#'TimeBase_UtcT'.inacchi, + (S#state.utc)#'TimeBase_UtcT'.inacclo)). +-define(get_Tdf(S), (S#state.utc)#'TimeBase_UtcT'.tdf). +-define(get_Utc(S), S#state.utc). +-define(get_TimeObj(S), S#state.timer). + + +%%-----------------------------------------------------------% +%% function : handle_info, code_change +%% Arguments: +%% Returns : +%% Effect : Functions demanded by the gen_server module. +%%------------------------------------------------------------ + +code_change(_OldVsn, State, _Extra) -> + {ok, State}. +handle_info(_Info, State) -> + {noreply, State}. + +%%----------------------------------------------------------% +%% function : init, terminate +%% Arguments: +%%----------------------------------------------------------- + +init([Utc, TimeObj]) -> + {ok, ?get_InitState(Utc, TimeObj)}. + +terminate(_Reason, _State) -> + ok. + +%%----------------------------------------------------------- +%%------------------------ attributes ----------------------- +%%----------------------------------------------------------- +%%----------------------------------------------------------% +%% Attribute: '_get_time' +%% Type : readonly +%% Returns : +%%----------------------------------------------------------- +'_get_time'(_OE_THIS, State) -> + {reply, ?get_Time(State), State}. + +%%----------------------------------------------------------% +%% Attribute: '_get_inaccuracy' +%% Type : readonly +%% Returns : +%%----------------------------------------------------------- +'_get_inaccuracy'(_OE_THIS, State) -> + {reply, ?get_Inaccuracy(State), State}. + +%%----------------------------------------------------------% +%% Attribute: '_get_tdf' +%% Type : readonly +%% Returns : +%%----------------------------------------------------------- +'_get_tdf'(_OE_THIS, State) -> + {reply, ?get_Tdf(State), State}. + +%%----------------------------------------------------------% +%% Attribute: '_get_utc_time' +%% Type : readonly +%% Returns : +%%----------------------------------------------------------- +'_get_utc_time'(_OE_THIS, State) -> + {reply, ?get_Utc(State), State}. + +%%----------------------------------------------------------- +%%------- Exported external functions ----------------------- +%%----------------------------------------------------------- +%%----------------------------------------------------------% +%% function : absolute_time +%% Arguments: - +%% Returns : UTO +%% NOTE : Return the base time to the relative time in the object. +%%----------------------------------------------------------- +absolute_time(_OE_THIS, State) -> + case catch 'CosTime_UTO':'_get_time'( + 'CosTime_TimeService':universal_time(?get_TimeObj(State)))+ + ?get_Time(State) of + UniTime when is_integer(UniTime) andalso UniTime =< ?max_TimeT -> + Utc=?get_Utc(State), + {reply, 'CosTime_UTO':oe_create([Utc#'TimeBase_UtcT'{time=UniTime}, + ?get_TimeObj(State)], + [{pseudo,true}|?CREATE_OPTS]), State}; + UniTime when is_integer(UniTime) -> + %% Oopss, overflow! + corba:raise(#'DATA_CONVERSION'{completion_status=?COMPLETED_NO}); + _ -> + corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO}) + end. + +%%----------------------------------------------------------% +%% function : compare_time +%% Arguments: Comparison_type - CosTime::ComparisonType +%% Uto - ObjRef +%% Returns : TimeComparison - 'TCEqualTo' | 'TCLessThan' | +%% 'TCGreaterThan' | 'TCIndeterminate' +%%----------------------------------------------------------- +compare_time(_OE_THIS, State, 'IntervalC', Uto) -> + ?time_TypeCheck(Uto, 'CosTime_UTO'), + case catch {'CosTime_UTO':'_get_time'(Uto), + 'CosTime_UTO':'_get_inaccuracy'(Uto)} of + {Time,Inaccuracy} when is_integer(Time) andalso is_integer(Inaccuracy) -> + OwnInacc = ?get_Inaccuracy(State), + if + ?get_Time(State)+OwnInacc < Time-Inaccuracy -> + {reply, 'TCLessThan', State}; + ?get_Time(State)-OwnInacc > Time+Inaccuracy -> + {reply, 'TCGreaterThan', State}; + ?get_Time(State) == Time, Inaccuracy==0, OwnInacc==0 -> + %% TimeService specification (july 1997, p14-7:2) states + %% that they are only equal if both UTO's Inaccuracy + %% equals zero. + {reply, 'TCEqualTo', State}; + true -> + {reply, 'TCIndeterminate', State} + end; + _ -> + corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}) + end; +compare_time(_OE_THIS, State, 'MidC', Uto) -> + ?time_TypeCheck(Uto, 'CosTime_UTO'), + case catch 'CosTime_UTO':'_get_time'(Uto) of + Time when is_integer(Time) -> + if + ?get_Time(State) < Time -> + {reply, 'TCLessThan', State}; + ?get_Time(State) > Time -> + {reply, 'TCGreaterThan', State}; + true -> + {reply, 'TCEqualTo', State} + end; + _ -> + corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}) + end; +compare_time(_OE_THIS, _State, _, _) -> + %% Comparison_type given not correct?! + corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}). + +%%----------------------------------------------------------% +%% function : time_to_interval +%% Arguments: +%% Returns : TIO +%%----------------------------------------------------------- +time_to_interval(_OE_THIS, State, Uto) -> + ?time_TypeCheck(Uto, 'CosTime_UTO'), + case catch 'CosTime_UTO':'_get_time'(Uto) of + Time when is_integer(Time) -> + OwnTime = ?get_Time(State), + if + Time > OwnTime -> + {reply, 'CosTime_TIO':oe_create([#'TimeBase_IntervalT'{lower_bound=OwnTime, + upper_bound=Time}, + ?get_Tdf(State), + ?get_TimeObj(State)], + [{pseudo,true}|?CREATE_OPTS]), State}; + true -> + {reply, 'CosTime_TIO':oe_create([#'TimeBase_IntervalT'{lower_bound=Time, + upper_bound=OwnTime}, + ?get_Tdf(State), + ?get_TimeObj(State)], + [{pseudo,true}|?CREATE_OPTS]), State} + end; + _ -> + corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}) + end. + +%%----------------------------------------------------------% +%% function : interval +%% Arguments: +%% Returns : TIO +%%----------------------------------------------------------- +interval(_OE_THIS, State) -> + Lower = ?get_Time(State) - ?get_Inaccuracy(State), + Upper = ?get_Time(State) + ?get_Inaccuracy(State), + {reply, 'CosTime_TIO':oe_create([#'TimeBase_IntervalT'{lower_bound=Lower, + upper_bound=Upper}, + ?get_Tdf(State), + ?get_TimeObj(State)], + [{pseudo,true}|?CREATE_OPTS]), State}. + + +%%--------------- LOCAL FUNCTIONS ---------------------------- + +%%--------------- MISC FUNCTIONS, E.G. DEBUGGING ------------- +%%--------------- END OF MODULE ------------------------------ + diff --git a/lib/cosTime/src/CosTimerEvent.cfg b/lib/cosTime/src/CosTimerEvent.cfg new file mode 100644 index 0000000000..7f16197168 --- /dev/null +++ b/lib/cosTime/src/CosTimerEvent.cfg @@ -0,0 +1,4 @@ +{this, "CosTimerEvent::TimerEventHandler"}. +{{handle_info, "CosTimerEvent::TimerEventHandler"}, true}. +{this, "CosTimerEvent::TimerEventService"}. +{{handle_info, "CosTimerEvent::TimerEventService"}, true}. diff --git a/lib/cosTime/src/CosTimerEvent.idl b/lib/cosTime/src/CosTimerEvent.idl new file mode 100644 index 0000000000..b845862f98 --- /dev/null +++ b/lib/cosTime/src/CosTimerEvent.idl @@ -0,0 +1,45 @@ +#ifndef _COS_TIMEREVENT_IDL_ +#define _COS_TIMEREVENT_IDL_ + +#pragma prefix "omg.org" + +#include"CosEventComm.idl" +#include<CosTime.idl> +#include<TimeBase.idl> + +module CosTimerEvent{ + + enum TimeType { + TTAbsolute, + TTRelative, + TTPeriodic + }; + enum EventStatus { + ESTimeSet, + ESTimeCleared, + ESTriggered, + ESFailedTrigger + }; + + struct TimerEventT { + TimeBase::UtcT utc; + any event_data; + }; + + interface TimerEventHandler { + readonly attribute EventStatus status; + boolean time_set( out CosTime::UTO uto ); + void set_timer( in TimeType time_type, in CosTime::UTO trigger_time ); + boolean cancel_timer(); + void set_data( in any event_data ); + }; + + interface TimerEventService { + + TimerEventHandler register( in CosEventComm::PushConsumer event_interface, in any data ); + void unregister( in TimerEventHandler timer_event_handler ); + CosTime::UTO event_time( in TimerEventT timer_event ); + }; +}; + +#endif diff --git a/lib/cosTime/src/CosTimerEvent_TimerEventHandler_impl.erl b/lib/cosTime/src/CosTimerEvent_TimerEventHandler_impl.erl new file mode 100644 index 0000000000..5885691e87 --- /dev/null +++ b/lib/cosTime/src/CosTimerEvent_TimerEventHandler_impl.erl @@ -0,0 +1,304 @@ +%%-------------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2000-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%---------------------------------------------------------------------- +%% File : CosTimerEvent_TimerEventHandler_impl.erl +%% Purpose : +%%---------------------------------------------------------------------- + +-module('CosTimerEvent_TimerEventHandler_impl'). + +%%--------------- INCLUDES ----------------------------------- +-include("cosTimeApp.hrl"). + + +%%--------------- EXPORTS ------------------------------------ +%%--------------- External ----------------------------------- +%% Attributes (external) +-export(['_get_status'/2]). +%% Interface functions +-export([time_set/2, set_timer/4]). +-export([cancel_timer/2, set_data/3]). + +%%--------------- gen_server specific exports ---------------- +-export([handle_info/2, code_change/3]). +-export([init/1, terminate/2]). + + +%% Data structures +-record(state, {parent, + parentPid, + event, + status = 'ESTimeCleared', + timer, + time, + timeObj, + myType, + pushConsumer, + uto}). +%% Data structures constructors +-define(get_InitState(P,PP,E,PC,TO), + #state{parent=P, + parentPid=PP, + event=E, + pushConsumer=PC, + timeObj=TO}). + +%% Data structures selectors +-define(get_Status(S), S#state.status). +-define(get_ParentPid(S), S#state.parentPid). +-define(get_Parent(S), S#state.parent). +-define(get_Event(S), S#state.event). +-define(get_Timer(S), S#state.timer). +-define(get_Time(S), S#state.time). +-define(get_TimeObj(S), S#state.timeObj). +-define(get_MyType(S), S#state.myType). +-define(get_PushConsumer(S), S#state.pushConsumer). +-define(get_Uto(S), S#state.uto). + +%% Data structures modifiers +-define(set_Status(S,V), S#state{status=V}). +-define(set_ParentPid(S,PP), S#state{parentPid=PP}). +-define(set_Parent(S,P), S#state{parent=P}). +-define(set_Event(S,E), S#state{event=E}). +-define(set_Timer(S,T), S#state{timer=T}). +-define(set_Time(S,T), S#state{time=T}). +-define(set_MyType(S,Ty), S#state{myType=Ty}). +-define(set_PushConsumer(S,P), S#state{pushConsumer=P}). +-define(set_Uto(S,U,Type), S#state{uto=U, myType=Type}). +-define(set_TimeData(S,U,Ty,Ti),S#state{uto=U, myType=Ty, time=Ti}). + +%% MISC +-define(not_Cancelled(S), S#state.status =/= 'ESTimeCleared'). +-define(is_TimeSet(S), S#state.status == 'ESTimeSet'). +-define(is_UtoSet(S), S#state.uto =/= undefined). +-define(is_NotAbsolute(S), S#state.myType =/= 'TTAbsolute'). + +%%-----------------------------------------------------------% +%% function : handle_info, code_change +%% Arguments: +%% Returns : +%% Effect : Functions demanded by the gen_server module. +%%------------------------------------------------------------ + +code_change(_OldVsn, State, _Extra) -> + {ok, State}. + +handle_info(Info, State) -> + ?debug_print("INFO: ~p~n", [Info]), + case Info of + {'EXIT', Pid, _Reason} when Pid == ?get_ParentPid(State) -> + ?debug_print("PARENT TERMINATED with reason: ~p~n",[_Reason]), + {noreply, State}; + oe_event when ?not_Cancelled(State) -> + %% Push event + case catch 'CosEventComm_PushConsumer':push(?get_PushConsumer(State), + ?get_Event(State)) of + ok -> + ?debug_print("PUSHED: ~p~n", [?get_Event(State)]), + {noreply, ?set_Status(State, 'ESTriggered')}; + _Other-> + ?debug_print("FAILED PUSH: ~p ~p~n", [?get_Event(State), _Other]), + {noreply, ?set_Status(State, 'ESFailedTrigger')} + end; + oe_periodic_event when ?not_Cancelled(State) -> + %% Push event + catch 'CosEventComm_PushConsumer':push(?get_PushConsumer(State), + ?get_Event(State)), + {noreply, State}; + _ -> + {noreply, State} + end. + +%%----------------------------------------------------------% +%% function : init, terminate +%% Arguments: +%%----------------------------------------------------------- + +init([Parent, ParentPid, PushConsumer, Event, TimeObj]) -> + process_flag(trap_exit, true), + {ok, ?get_InitState(Parent, ParentPid, Event, PushConsumer, TimeObj)}. + +terminate(_Reason, State) -> + clear_timer(State), + ok. + +%%----------------------------------------------------------- +%%------------------------ attributes ----------------------- +%%----------------------------------------------------------- +%%----------------------------------------------------------% +%% Attribute: '_get_status' +%% Type : readonly +%% Returns : 'ESTimeSet' | 'ESTimeCleared' | 'ESTriggered' | +%% 'ESFailedTrigger' +%%----------------------------------------------------------- +'_get_status'(_OE_THIS, State) -> + {reply, ?get_Status(State), State}. + +%%----------------------------------------------------------- +%%------- Exported external functions ----------------------- +%%----------------------------------------------------------- +%%----------------------------------------------------------% +%% function : time_set +%% Arguments: - +%% Returns : {boolean(), CosTime::UTO} +%%----------------------------------------------------------- +time_set(_OE_THIS, State) when ?is_UtoSet(State) -> + {reply, {?is_TimeSet(State), ?get_Uto(State)}, State}; +time_set(_OE_THIS, State) -> + Utc = #'TimeBase_UtcT'{time=0, inacclo = 0,inacchi = 0, tdf = 0}, + {reply, + {?is_TimeSet(State), + 'CosTime_UTO':oe_create([Utc, ?get_TimeObj(State)], [{pseudo,true}|?CREATE_OPTS])}, + State}. + + +%%----------------------------------------------------------- +%% function : set_timer +%% Arguments: TimeType - 'TTAbsolute' | 'TTRelative' | 'TTPeriodic' +%% TriggerTime - CosTime::UTO +%% Returns : ok +%%----------------------------------------------------------- +set_timer(_OE_THIS, State, 'TTAbsolute', TriggerTime) -> + NewState = clear_timer(State), + ?time_TypeCheck(TriggerTime, 'CosTime_UTO'), + case catch {'CosTime_UTO':'_get_time'(TriggerTime), + 'CosTime_UTO':'_get_time'( + 'CosTime_TimeService':universal_time(?get_TimeObj(State)))} of + {Time, CurrentTime} when is_integer(Time) andalso is_integer(CurrentTime) andalso + Time > CurrentTime -> + %% Set a timer to send a message in (Time-CurrentTime)*10^-7 secs. + case timer:send_after(?convert_TimeT2TimerT(Time-CurrentTime), oe_event) of + {ok, TRef} -> + NewState1 = ?set_Timer(NewState, TRef), + NewState2 = ?set_Uto(NewState1, TriggerTime, 'TTAbsolute'), + ?debug_print("TIMER SET: ~p~n", [?convert_TimeT2TimerT(Time-CurrentTime)]), + {reply, ok, ?set_Status(NewState2, 'ESTimeSet')}; + _-> + corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO}) + end; + {Time, CurrentTime} when is_integer(Time) andalso is_integer(CurrentTime) -> + corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}); + _-> + corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO}) + end; +set_timer(_OE_THIS, State, 'TTRelative', TriggerTime) -> + NewState = clear_timer(State), + ?time_TypeCheck(TriggerTime, 'CosTime_UTO'), + case catch {'CosTime_UTO':'_get_time'(TriggerTime), ?get_Time(State)} of + {0,OldTime} when ?is_NotAbsolute(NewState) andalso is_integer(OldTime) -> + %% Set a timer to send a message within Time*10^-7 secs + case timer:send_after(OldTime, oe_event) of + {ok, TRef} -> + NewState1 = ?set_Timer(NewState, TRef), + NewState2 = ?set_Uto(NewState1, TriggerTime, 'TTRelative'), + ?debug_print("TIMER SET: ~p~n", [?convert_TimeT2TimerT(OldTime)]), + {reply, ok, ?set_Status(NewState2, 'ESTimeSet')}; + _-> + corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO}) + end; + {UtoTime,_} when is_integer(UtoTime) -> + %% Set a timer to send a message within Time*10^-7 secs + Time = ?convert_TimeT2TimerT(UtoTime), + case timer:send_after(Time, oe_event) of + {ok, TRef} -> + NewState1 = ?set_Timer(NewState, TRef), + NewState2 = ?set_TimeData(NewState1, TriggerTime, + 'TTRelative', Time), + ?debug_print("TIMER SET: ~p~n", [?convert_TimeT2TimerT(Time)]), + {reply, ok, ?set_Status(NewState2, 'ESTimeSet')}; + _-> + corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO}) + end; + + _-> + {reply, {'EXCEPTION', #'BAD_PARAM'{completion_status=?COMPLETED_NO}}, NewState} + end; +set_timer(_OE_THIS, State, 'TTPeriodic', TriggerTime) -> + NewState = clear_timer(State), + ?time_TypeCheck(TriggerTime, 'CosTime_UTO'), + case catch {'CosTime_UTO':'_get_time'(TriggerTime), ?get_Time(State)} of + {0,OldTime} when ?is_NotAbsolute(NewState) andalso is_integer(OldTime) -> + %% Set a timer to send a message within Time*10^-7 secs + case timer:send_interval(OldTime, oe_periodic_event) of + {ok, TRef} -> + NewState1 = ?set_Timer(NewState, TRef), + NewState2 = ?set_Uto(NewState1, TriggerTime, 'TTPeriodic'), + ?debug_print("TIMER SET: ~p~n", [?convert_TimeT2TimerT(OldTime)]), + {reply, ok, ?set_Status(NewState2, 'ESTimeSet')}; + _-> + corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO}) + end; + {UtoTime,_} when is_integer(UtoTime) -> + %% Set a timer to send a message within Time*10^-7 secs + Time = ?convert_TimeT2TimerT(UtoTime), + case timer:send_interval(Time, oe_periodic_event) of + {ok, TRef} -> + NewState1 = ?set_Timer(NewState, TRef), + NewState2 = ?set_TimeData(NewState1, TriggerTime, + 'TTPeriodic', Time), + ?debug_print("TIMER SET: ~p~n", [?convert_TimeT2TimerT(Time)]), + {reply, ok, ?set_Status(NewState2, 'ESTimeSet')}; + _-> + corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO}) + end; + + _-> + {reply, {'EXCEPTION', #'BAD_PARAM'{completion_status=?COMPLETED_NO}}, NewState} + end; +set_timer(_OE_THIS, _State, _, _) -> + corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}). + +%%----------------------------------------------------------% +%% function : cancel_timer +%% Arguments: - +%% Returns : boolean() +%%----------------------------------------------------------- +cancel_timer(_OE_THIS, State) -> + NewState=clear_timer(State), + case ?get_Status(NewState) of + 'ESTriggered' -> + {reply, false, NewState}; + 'ESFailedTrigger' -> + {reply, false, NewState}; + _ -> + {reply, true, ?set_Status(NewState, 'ESTimeCleared')} + end. + +%%----------------------------------------------------------% +%% function : set_data +%% Arguments: EventData - any# +%% Returns : ok +%%----------------------------------------------------------- +set_data(_OE_THIS, State, EventData) when is_record(EventData, any) -> + {reply, ok, ?set_Event(State, EventData)}; +set_data(_OE_THIS, _State, _EventData) -> + corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}). + + +%%--------------- LOCAL FUNCTIONS ---------------------------- +clear_timer(State) when ?get_Timer(State) == undefined -> + State; +clear_timer(State) -> + catch timer:cancel(?get_Timer(State)), + ?set_Timer(State, undefined). + +%%--------------- MISC FUNCTIONS, E.G. DEBUGGING ------------- +%%--------------- END OF MODULE ------------------------------ diff --git a/lib/cosTime/src/CosTimerEvent_TimerEventService_impl.erl b/lib/cosTime/src/CosTimerEvent_TimerEventService_impl.erl new file mode 100644 index 0000000000..b324ecbecd --- /dev/null +++ b/lib/cosTime/src/CosTimerEvent_TimerEventService_impl.erl @@ -0,0 +1,118 @@ +%%-------------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2000-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%---------------------------------------------------------------------- +%% File : CosTimerEvent_TimerEventService_impl.erl +%% Purpose : +%%---------------------------------------------------------------------- + +-module('CosTimerEvent_TimerEventService_impl'). + +%%--------------- INCLUDES ----------------------------------- +-include("cosTimeApp.hrl"). + + +%%--------------- EXPORTS ------------------------------------ +%%--------------- External ----------------------------------- +%% Interface functions +-export([register/4, unregister/3, event_time/3]). + +%%--------------- gen_server specific exports ---------------- +-export([handle_info/2, code_change/3]). +-export([init/1, terminate/2]). + + +%% Data structures +-record(state, {timer}). +%% Data structures constructors +-define(get_InitState(T), + #state{timer=T}). + +%% Data structures selectors +-define(get_TimerObj(S), S#state.timer). + +%% Data structures modifiers + +%% MISC + +%%-----------------------------------------------------------% +%% function : handle_info, code_change +%% Arguments: +%% Returns : +%% Effect : Functions demanded by the gen_server module. +%%------------------------------------------------------------ + +code_change(_OldVsn, State, _Extra) -> + {ok, State}. + +handle_info(_Info, State) -> + ?debug_print("INFO: ~p~n", [_Info]), + {noreply, State}. + +%%----------------------------------------------------------% +%% function : init, terminate +%% Arguments: +%%----------------------------------------------------------- + +init([Timer]) -> + process_flag(trap_exit, true), + timer:start(), + {ok, ?get_InitState(Timer)}. + +terminate(_Reason, _State) -> + ok. + +%%----------------------------------------------------------- +%%------- Exported external functions ----------------------- +%%----------------------------------------------------------- +%%----------------------------------------------------------% +%% function : register +%% Arguments: EventInterface - CosEventComm::PushConsumer +%% Data - #any +%% Returns : TimerEventHandler - objref# +%%----------------------------------------------------------- +register(OE_THIS, State, EventInterface, Data) -> + {reply, + cosTime:start_event_handler([OE_THIS, self(),EventInterface, Data, + ?get_TimerObj(State)]), + State}. + +%%----------------------------------------------------------% +%% function : unregister +%% Arguments: TimerEventHandler - objref# +%% Returns : ok +%%----------------------------------------------------------- +unregister(_OE_THIS, State, TimerEventHandler) -> + catch corba:dispose(TimerEventHandler), + {reply, ok, State}. + +%%----------------------------------------------------------% +%% function : event_time +%% Arguments: TimerEvent - #'CosTimerEvent_TimerEventT'{utc, event_data} +%% Returns : CosTime::UTO +%%----------------------------------------------------------- +event_time(_OE_THIS, State, #'CosTimerEvent_TimerEventT'{utc=Utc}) -> + {reply, 'CosTime_UTO':oe_create([Utc],[{pseudo,true}]), State}. + + +%%--------------- LOCAL FUNCTIONS ---------------------------- + +%%--------------- MISC FUNCTIONS, E.G. DEBUGGING ------------- +%%--------------- END OF MODULE ------------------------------ diff --git a/lib/cosTime/src/Makefile b/lib/cosTime/src/Makefile new file mode 100644 index 0000000000..3b6f7bae2e --- /dev/null +++ b/lib/cosTime/src/Makefile @@ -0,0 +1,205 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 2000-2009. All Rights Reserved. +# +# The contents of this file are subject to the Erlang Public License, +# Version 1.1, (the "License"); you may not use this file except in +# compliance with the License. You should have received a copy of the +# Erlang Public License along with this software. If not, it can be +# retrieved online at http://www.erlang.org/. +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +# the License for the specific language governing rights and limitations +# under the License. +# +# %CopyrightEnd% +# +# +include $(ERL_TOP)/make/target.mk + +ifeq ($(TYPE),debug) +ERL_COMPILE_FLAGS += -Ddebug -W +endif + +include $(ERL_TOP)/make/$(TARGET)/otp.mk + +# ---------------------------------------------------- +# Application version +# ---------------------------------------------------- +include ../vsn.mk +VSN=$(COSTIME_VSN) + +# ---------------------------------------------------- +# Release directory specification +# ---------------------------------------------------- +RELSYSDIR = $(RELEASE_PATH)/lib/cosTime-$(VSN) + +EXTERNAL_INC_PATH = ../include + +# ---------------------------------------------------- +# Target Specs +# ---------------------------------------------------- + +MODULES = \ + cosTime \ + CosTime_TIO_impl \ + CosTime_TimeService_impl \ + CosTime_UTO_impl \ + CosTimerEvent_TimerEventHandler_impl \ + CosTimerEvent_TimerEventService_impl \ + +ERL_FILES = $(MODULES:%=%.erl) +HRL_FILES = \ + cosTimeApp.hrl \ + +GEN_TIMEBASE_ERL_FILES = \ + oe_TimeBase.erl \ + TimeBase_IntervalT.erl \ + TimeBase_UtcT.erl + +GEN_COSTIME_ERL_FILES = \ + oe_CosTime.erl \ + CosTime_TIO.erl \ + CosTime_TimeService.erl \ + CosTime_TimeUnavailable.erl \ + CosTime_UTO.erl \ + +GEN_COSTIMEREVENT_ERL_FILES = \ + oe_CosTimerEvent.erl \ + CosTimerEvent_TimerEventHandler.erl \ + CosTimerEvent_TimerEventService.erl \ + CosTimerEvent_TimerEventT.erl \ + +GEN_TIMEBASE_HRL_FILES = \ + oe_TimeBase.hrl \ + TimeBase.hrl \ + +EXTERNAL_TIMEBASE_HRL_FILES = $(GEN_TIMEBASE_HRL_FILES:%=$(EXTERNAL_INC_PATH)/%) + +GEN_COSTIME_HRL_FILES = \ + oe_CosTime.hrl \ + CosTime.hrl \ + CosTime_TIO.hrl \ + CosTime_TimeService.hrl \ + CosTime_UTO.hrl + +EXTERNAL_COSTIME_HRL_FILES = $(GEN_COSTIME_HRL_FILES:%=$(EXTERNAL_INC_PATH)/%) + +GEN_COSTIMEREVENT_HRL_FILES = \ + oe_CosTimerEvent.hrl \ + CosTimerEvent.hrl \ + CosTimerEvent_TimerEventHandler.hrl \ + CosTimerEvent_TimerEventService.hrl \ + +EXTERNAL_COSTIMEREVENT_HRL_FILES = $(GEN_COSTIMEREVENT_HRL_FILES:%=$(EXTERNAL_INC_PATH)/%) + + +GEN_ERL_FILES = \ + $(GEN_TIMEBASE_ERL_FILES) \ + $(GEN_COSTIME_ERL_FILES) \ + $(GEN_COSTIMEREVENT_ERL_FILES) + +GEN_HRL_FILES = \ + $(EXTERNAL_TIMEBASE_HRL_FILES) \ + $(EXTERNAL_COSTIME_HRL_FILES) \ + $(EXTERNAL_COSTIMEREVENT_HRL_FILES) \ + +GEN_FILES = \ + $(GEN_HRL_FILES) \ + $(GEN_ERL_FILES) + +TARGET_FILES = \ + $(GEN_TIMEBASE_ERL_FILES:%.erl=$(EBIN)/%.$(EMULATOR)) \ + $(GEN_COSTIME_ERL_FILES:%.erl=$(EBIN)/%.$(EMULATOR)) \ + $(GEN_COSTIMEREVENT_ERL_FILES:%.erl=$(EBIN)/%.$(EMULATOR)) \ + $(MODULES:%=$(EBIN)/%.$(EMULATOR)) + +IDL_FILES = \ + TimeBase.idl \ + CosTime.idl \ + CosTimerEvent.idl + +APPUP_FILE = cosTime.appup +APPUP_SRC = $(APPUP_FILE).src +APPUP_TARGET = $(EBIN)/$(APPUP_FILE) + +APP_FILE = cosTime.app +APP_SRC = $(APP_FILE).src +APP_TARGET = $(EBIN)/$(APP_FILE) + +# ---------------------------------------------------- +# FLAGS +# ---------------------------------------------------- +ERL_IDL_FLAGS += -pa $(ERL_TOP)/lib/cosTime/ebin \ + -pa $(ERL_TOP)/lib/ic/ebin\ + -pa $(ERL_TOP)/lib/orber/ebin \ + -I$(ERL_TOP)/lib/cosEvent/src + +# The -pa option is just used temporary until erlc can handle +# includes from other directories than ../include . +ERL_COMPILE_FLAGS += \ + $(ERL_IDL_FLAGS) \ + -pa $(ERL_TOP)/lib/orber/include \ + -pa $(ERL_TOP)/lib/cosTime/include \ + -I$(ERL_TOP)/lib/cosTime/include \ + -I$(ERL_TOP)/lib/orber/include \ + +'{parse_transform,sys_pre_attributes}' \ + +'{attribute,insert,app_vsn,"cosTime_$(COSTIME_VSN)"}' + + +# ---------------------------------------------------- +# Targets +# ---------------------------------------------------- +opt: $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) + +debug: + @${MAKE} TYPE=debug opt + +cleanb: + rm -f $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) + rm -f errs core *~ + +clean: + rm -f $(TARGET_FILES) $(GEN_FILES) $(APP_TARGET) $(APPUP_TARGET) + rm -f errs core *~ + +$(APP_TARGET): $(APP_SRC) + sed -e 's;%VSN%;$(VSN);' $< > $@ + +$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk + sed -e 's;%VSN%;$(VSN);' $< > $@ + +docs: + +# ---------------------------------------------------- +# Special Build Targets +# ---------------------------------------------------- +$(GEN_TIMEBASE_ERL_FILES) $(EXTERNAL_TIMEBASE_HRL_FILES): TimeBase.idl + erlc $(ERL_IDL_FLAGS) TimeBase.idl + mv $(GEN_TIMEBASE_HRL_FILES) $(EXTERNAL_INC_PATH) + +$(GEN_COSTIME_ERL_FILES) $(EXTERNAL_COSTIME_HRL_FILES): CosTime.idl + erlc $(ERL_IDL_FLAGS) +'{cfgfile,"CosTime.cfg"}' CosTime.idl + mv $(GEN_COSTIME_HRL_FILES) $(EXTERNAL_INC_PATH) + +$(GEN_COSTIMEREVENT_ERL_FILES) $(EXTERNAL_COSTIMEREVENT_HRL_FILES): CosTimerEvent.idl + erlc $(ERL_IDL_FLAGS) +'{cfgfile,"CosTimerEvent.cfg"}' CosTimerEvent.idl + mv $(GEN_COSTIMEREVENT_HRL_FILES) $(EXTERNAL_INC_PATH) + +# ---------------------------------------------------- +# Release Target +# ---------------------------------------------------- +include $(ERL_TOP)/make/otp_release_targets.mk + +release_spec: opt + $(INSTALL_DIR) $(RELSYSDIR)/ebin + $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) $(RELSYSDIR)/ebin + $(INSTALL_DIR) $(RELSYSDIR)/src + $(INSTALL_DATA) $(GEN_FILES) $(IDL_FILES) $(RELSYSDIR)/src + $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(GEN_ERL_FILES) $(IDL_FILES) $(RELSYSDIR)/src + $(INSTALL_DIR) $(RELSYSDIR)/include + $(INSTALL_DATA) $(GEN_HRL_FILES) $(RELSYSDIR)/include + +release_docs_spec: diff --git a/lib/cosTime/src/TimeBase.idl b/lib/cosTime/src/TimeBase.idl new file mode 100644 index 0000000000..92a0c652d8 --- /dev/null +++ b/lib/cosTime/src/TimeBase.idl @@ -0,0 +1,22 @@ +#ifndef _TIMEBASE_IDL_ +#define _TIMEBASE_IDL_ + +#pragma prefix "omg.org" + +module TimeBase { + typedef unsigned long long TimeT; + typedef TimeT InaccuracyT; + typedef short TdfT; + struct UtcT { + TimeT time; // 8 octets + unsigned long inacclo; // 4 octets + unsigned short inacchi; // 2 octets + TdfT tdf; // 2 octets // total 16 octets. + }; + struct IntervalT { + TimeT lower_bound; + TimeT upper_bound; + }; +}; + +#endif diff --git a/lib/cosTime/src/cosTime.app.src b/lib/cosTime/src/cosTime.app.src new file mode 100644 index 0000000000..191ee5f3db --- /dev/null +++ b/lib/cosTime/src/cosTime.app.src @@ -0,0 +1,30 @@ +{application, cosTime, + [{description, "The Erlang CosTime application"}, + {vsn, "%VSN%"}, + {modules, + [ + 'cosTime', + 'oe_TimeBase', + 'oe_CosTime', + 'oe_CosTimerEvent', + 'CosTime_TIO', + 'CosTime_TimeService', + 'CosTime_TimeUnavailable', + 'CosTime_UTO', + 'CosTimerEvent_TimerEventHandler', + 'CosTimerEvent_TimerEventService', + 'CosTimerEvent_TimerEventT', + 'TimeBase_IntervalT', + 'TimeBase_UtcT', + 'CosTime_TIO_impl', + 'CosTime_TimeService_impl', + 'CosTime_UTO_impl', + 'CosTimerEvent_TimerEventHandler_impl', + 'CosTimerEvent_TimerEventService_impl' + ] + }, + {registered, [oe_cosTimeSup, oe_cosTimerEventService]}, + {applications, [orber, stdlib, kernel]}, + {env, []}, + {mod, {cosTime, []}} +]}. diff --git a/lib/cosTime/src/cosTime.appup.src b/lib/cosTime/src/cosTime.appup.src new file mode 100644 index 0000000000..f3eead4a0c --- /dev/null +++ b/lib/cosTime/src/cosTime.appup.src @@ -0,0 +1,6 @@ +{"%VSN%", + [ + ], + [ + ] +}. diff --git a/lib/cosTime/src/cosTime.erl b/lib/cosTime/src/cosTime.erl new file mode 100644 index 0000000000..f4e67570ad --- /dev/null +++ b/lib/cosTime/src/cosTime.erl @@ -0,0 +1,321 @@ +%%-------------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2000-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%---------------------------------------------------------------------- +%% File : cosTime.erl +%% Purpose : +%%---------------------------------------------------------------------- + +-module(cosTime). + +%%--------------- INCLUDES ----------------------------------- +-include("cosTimeApp.hrl"). + +%%--------------- EXPORTS------------------------------------- +%% cosTime API external +-export([start/0, stop/0, + install_time/0, uninstall_time/0, + install_timerevent/0, uninstall_timerevent/0, + start_time_service/2, start_timerevent_service/1, stop_timerevent_service/1, + stop_time_service/1]). + +%% cosTime API internal +-export([create_link/3, get_option/3, type_check/2, start_event_handler/1]). + +%% Application callbacks +-export([start/2, init/1, stop/1]). + +%%--------------- DEFINES ------------------------------------ +-define(IDL_TIME_MODULES, ['oe_TimeBase', + 'oe_CosTime']). +-define(IDL_TIMEREVENT_MODULES, ['oe_CosTimerEvent']). +-define(SUPERVISOR_NAME, oe_cosTimeSup). +-define(SUP_FLAG, {simple_one_for_one,50,10}). +-define(SUP_TIMESERVICE_SPEC(T,I), + ['CosTime_TimeService',[T, I], + [{sup_child, true}, {regname, {global, "oe_cosTimeService"}}]]). +-define(SUP_TIMEREVENTSERVICE_SPEC(Args), + ['CosTimerEvent_TimerEventService', Args, + [{sup_child, true}, {regname, {local, 'oe_cosTimerEventService'}}]]). +-define(SUP_TIMEREVENTHANDLER_SPEC(Name, Args), + ['CosTimerEvent_TimerEventHandler',Args, + [{sup_child, true}, {regname, {global, Name}}]]). +-define(SUP_CHILD, + {"oe_TimeChild", + {cosTime,create_link, []}, + transient,100000,worker, + []}). + +%%------------------------------------------------------------ +%% function : install_*/X +%% Arguments: - | Time (seconds) +%% Returns : ok | EXIT | EXCEPTION +%% Effect : Install necessary data in the IFR DB +%%------------------------------------------------------------ + +install_time() -> + install_loop(?IDL_TIME_MODULES,[]). + +install_timerevent() -> + install_loop(?IDL_TIMEREVENT_MODULES,[]). + +install_loop([], _) -> + ok; +install_loop([H|T], Accum) -> + case catch H:'oe_register'() of + {'EXIT',{unregistered,App}} -> + ?write_ErrorMsg("Unable to register '~p'; application ~p not registered. +Trying to unregister ~p~n", [H,App,Accum]), + uninstall_loop(Accum, {exit, register}); + {'EXCEPTION',_} -> + ?write_ErrorMsg("Unable to register '~p'; propably already registered. +You are adviced to confirm this. +Trying to unregister ~p~n", [H,Accum]), + uninstall_loop(Accum, {exit, register}); + ok -> + install_loop(T, [H|Accum]); + _ -> + ?write_ErrorMsg("Unable to register '~p'; reason unknown. +Trying to unregister ~p~n", [H,Accum]), + uninstall_loop(Accum, {exit, register}) + end. + +%%------------------------------------------------------------ +%% function : uninstall_*/X +%% Arguments: - | Time (seconds) +%% Returns : ok | EXIT | EXCEPTION +%% Effect : Remove data related to cosTime from the IFR DB +%%------------------------------------------------------------ + +uninstall_time() -> + uninstall_loop(lists:reverse(?IDL_TIME_MODULES),ok). + +uninstall_timerevent() -> + uninstall_loop(lists:reverse(?IDL_TIMEREVENT_MODULES),ok). + +uninstall_loop([],ok) -> + ok; +uninstall_loop([],{exit, register}) -> + exit({?MODULE, "oe_register failed"}); +uninstall_loop([],{exit, unregister}) -> + exit({?MODULE, "oe_unregister failed"}); +uninstall_loop([],{exit, both}) -> + exit({?MODULE, "oe_register and, for some of those already registered, oe_unregister failed"}); +uninstall_loop([H|T], Status) -> + case catch H:'oe_unregister'() of + ok -> + uninstall_loop(T, Status); + _ when Status == ok -> + ?write_ErrorMsg("Unable to unregister '~p'; propably already unregistered. +You are adviced to confirm this.~n",[H]), + uninstall_loop(T, {exit, unregister}); + _ -> + ?write_ErrorMsg("Unable to unregister '~p'; propably already unregistered. +You are adviced to confirm this.~n",[H]), + uninstall_loop(T, {exit, both}) + end. + +%%------------------------------------------------------------ +%% function : start/stop +%% Arguments: +%% Returns : +%% Effect : Starts or stops the cosTime application. +%%------------------------------------------------------------ + +start() -> + application:start(cosTime). +stop() -> + application:stop(cosTime). + +%%------------------------------------------------------------ +%% function : start +%% Arguments: Type - see module application +%% Arg - see module application +%% Returns : +%% Effect : Module callback for application +%%------------------------------------------------------------ + +start(_, _) -> + supervisor:start_link({local, ?SUPERVISOR_NAME}, cosTime, app_init). + + +%%------------------------------------------------------------ +%% function : stop +%% Arguments: Arg - see module application +%% Returns : +%% Effect : Module callback for application +%%------------------------------------------------------------ + +stop(_) -> + ok. + +%%------------------------------------------------------------ +%% function : start_time_service +%% Arguments: Tdf - time difference to UTC +%% Inaccuracy - ulonglong +%% Upper - inaccuracy high +%% Returns : +%% Effect : +%%------------------------------------------------------------ +start_time_service(Tdf, Inaccuracy) when is_integer(Tdf) andalso is_integer(Inaccuracy) -> + case supervisor:start_child(?SUPERVISOR_NAME, + ?SUP_TIMESERVICE_SPEC(Tdf, Inaccuracy)) of + {ok, Pid, Obj} when is_pid(Pid) -> + Obj; + _Other-> + corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO}) + end; +start_time_service(_Tdf, _Inaccuracy) -> + corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}). + + +%%------------------------------------------------------------ +%% function : stop_time_service +%% Arguments: Obj - TimeService objref +%% Returns : +%% Effect : +%%------------------------------------------------------------ +stop_time_service(Obj) -> + corba:dispose(Obj). + +%%------------------------------------------------------------ +%% function : start_timerevent_service +%% Arguments: Timer - Timer Service Reference +%% Returns : +%% Effect : +%%------------------------------------------------------------ +start_timerevent_service(Timer) -> + case supervisor:start_child(?SUPERVISOR_NAME, + ?SUP_TIMEREVENTSERVICE_SPEC([Timer])) of + {ok, Pid, Obj} when is_pid(Pid) -> + Obj; + _Other-> + corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO}) + end. + +%%-----------------------------------------------------------% +%% function : stop_timerevent_service +%% Arguments: Obj - TimerEventService objref +%% Returns : +%% Effect : +%%------------------------------------------------------------ +stop_timerevent_service(Obj) -> + corba:dispose(Obj). + +%%-----------------------------------------------------------% +%% function : init +%% Arguments: +%% Returns : +%% Effect : +%%------------------------------------------------------------ + +%% Starting using create_factory/X +init(own_init) -> + {ok,{?SUP_FLAG, [?SUP_CHILD]}}; +%% When starting as an application. +init(app_init) -> + {ok,{?SUP_FLAG, [?SUP_CHILD]}}. + +%%-----------------------------------------------------------% +%% function : create_link +%% Arguments: Module - which Module to call +%% Env/ArgList - ordinary oe_create arguments. +%% Returns : +%% Exception: +%% Effect : Necessary since we want the supervisor to be a +%% 'simple_one_for_one'. Otherwise, using for example, +%% 'one_for_one', we have to call supervisor:delete_child +%% to remove the childs startspecification from the +%% supervisors internal state. +%%------------------------------------------------------------ +create_link(Module, Env, ArgList) -> + Module:oe_create_link(Env, ArgList). + +%%-----------------------------------------------------------% +%% function : start_event_handler +%% Arguments: +%% Returns : +%% Exception: +%% Effect : +%%------------------------------------------------------------ + +start_event_handler(Args) -> + Name = create_name(eventhandler), + case supervisor:start_child(?SUPERVISOR_NAME, ?SUP_TIMEREVENTHANDLER_SPEC(Name,Args)) of + {ok, Pid, Obj} when is_pid(Pid) -> + Obj; + _Other-> + corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO}) + end. + + +%%-----------------------------------------------------------% +%% function : get_option +%% Arguments: +%% Returns : +%% Exception: +%% Effect : +%%------------------------------------------------------------ + +get_option(Key, OptionList, DefaultList) -> + case lists:keysearch(Key, 1, OptionList) of + {value,{Key,Value}} -> + Value; + _ -> + case lists:keysearch(Key, 1, DefaultList) of + {value,{Key,Value}} -> + Value; + _-> + {error, "Invalid option"} + end + end. + +%%-----------------------------------------------------------% +%% function : type_check +%% Arguments: Obj - objectrefernce to test. +%% Mod - Module which contains typeID/0. +%% Returns : 'ok' or raises exception. +%% Effect : +%%------------------------------------------------------------ + +type_check(Obj, Mod) -> + case catch corba_object:is_a(Obj,Mod:typeID()) of + true -> + ok; + _ -> + corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}) + end. + + +%%-----------------------------------------------------------% +%% function : create_name/1 +%% Arguments: +%% Returns : +%% Exception: +%% Effect : +%%------------------------------------------------------------ + +create_name(Type) -> + {MSec, Sec, USec} = erlang:now(), + lists:concat(['oe_',node(),'_',Type,'_',MSec, '_', Sec, '_', USec]). + +%%--------------- END OF MODULE ------------------------------ + + diff --git a/lib/cosTime/src/cosTimeApp.hrl b/lib/cosTime/src/cosTimeApp.hrl new file mode 100644 index 0000000000..f3082816f7 --- /dev/null +++ b/lib/cosTime/src/cosTimeApp.hrl @@ -0,0 +1,76 @@ +%%---------------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2000-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%---------------------------------------------------------------------- +%% File : cosTimeApp.hrl +%% Purpose : +%%---------------------------------------------------------------------- + + +%%--------------- INCLUDES ----------------------------------- +%% External +-include_lib("orber/include/corba.hrl"). +-include_lib("orber/include/ifr_types.hrl"). + +%% Local +-include("CosTimerEvent.hrl"). +-include("CosTime.hrl"). +-include("CosTimerEvent.hrl"). +-include("TimeBase.hrl"). + +-define(CREATE_OPTS, [{no_security, orber:partial_security()}]). + +-define(max_Inaccuracy, 281474976710655). +-define(max_TimeT, 18446744073709551616). + +%% The calendar module uses year 0 as base for gregorian functions. +%% 'ABSOULTE_TIME_DIFF' is #seconfs from year 0 until 15 october 1582, 00:00. +-define(ABSOLUTE_TIME_DIFF, 49947926400). +%% As above but diff year 0 to 00:00 GMT, January 1, 1970 +-define(STANDARD_TIME_DIFF, 62167219200). + +-define(split_TimeT(T), {((T band 16#0000ffff00000000) bsr 32), + (T band 16#00000000ffffffff)}). + +-define(high_TimeT(T), ((T band 16#0000ffff00000000) bsr 32)). +-define(low_TimeT(T), (T band 16#00000000ffffffff)). + +-define(concat_TimeT(H,L), ((H bsl 32) + L)). + +-define(convert_TimeT2TimerT(N), erlang:trunc(N*1.0e-4)). + +-define(write_ErrorMsg(Txt, Arg), +error_logger:error_msg("================ CosTime ==================~n" + Txt + "===========================================~n", + Arg)). + + + +-ifdef(debug). +-define(debug_print(F,A), + io:format("[LINE: ~p MODULE: ~p] "++F,[?LINE, ?MODULE]++A)). +-define(time_TypeCheck(O,M), 'cosTime':type_check(O,M)). +-else. +-define(debug_print(F,A), ok). +-define(time_TypeCheck(O,I), ok). +-endif. + +%%--------------- END OF MODULE ------------------------------ |