2 * $Id: htimerNtp.c,v 0.0.0.1 2003/08/21
4 * DEBUG: section 2 HTimer for NtpTime
6 * -------------------------------------------------------------------
8 * Open Real-Time Ethernet
10 * Copyright (C) 2001-2006
11 * Department of Control Engineering FEE CTU Prague, Czech Republic
12 * http://dce.felk.cvut.cz
13 * http://www.ocera.org
15 * Author: Petr Smolik petr@smoliku.cz
17 * Project Responsible: Zdenek Hanzalek
18 * --------------------------------------------------------------------
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
32 #define UL_HTIMER_INC_FROM_BASE
36 GAVL_FLES_INT_DEC(ul_htim_queue, /* prefix */
37 ul_htim_queue_t, /* root_t */
38 ul_htim_node_t, /* item_t */
39 ul_htim_time_t, /* key_t */
40 timers, /* root_field */
42 expires, /* item_key */
43 ul_htimer_cmp_fnc) /* cmp_fnc */
46 GAVL_FLES_INT_IMP(ul_htim_queue, ul_htim_queue_t, ul_htim_node_t, ul_htim_time_t,
47 timers, node, expires, ul_htimer_cmp_fnc, GAVL_FAFTER,
48 root->first_changed = 1,;
49 , root->first_changed = 1)
51 /*****************************************************************************/
52 UL_HTIMER_IMP(htimerRoot, \
58 htimerRoot_run_expired(ORTEDomain *d,
59 ul_htim_time_t *pact_time)
61 HTimFncRootNode *timer;
63 debug(2, 10) ("htimerRoot: start\n");
64 while ((timer = htimerRoot_cut_expired(&d->objectEntry, pact_time))) {
65 debug(2, 10) ("htimerRoot: AID-0x%x\n", timer->objectEntryAID->aid);
66 timer->func(d, timer->objectEntryAID, pact_time);
68 debug(2, 10) ("htimerRoot: finished\n");
71 /*****************************************************************************/
72 UL_HTIMER_IMP(htimerUnicastCommon, \
79 htimerUnicastCommon_update_root_timer(ObjectEntry *objectEntry,
80 ObjectEntryAID *objectEntryAID)
84 //if first item is changed -> update root timer queue
85 if (htimerUnicastCommon_first_changed(objectEntryAID)) {
86 //deatach old timer from this queue (if any)
87 htimerRoot_detach(objectEntry,
88 &objectEntryAID->htimUnicast.commonNode);
89 if (htimerUnicastCommon_next_expire(objectEntryAID, &nextExpire) != 0) {
91 objectEntryAID->htimUnicast.commonNode.func =
92 htimerUnicastCommon_run_expired;
93 objectEntryAID->htimUnicast.commonNode.objectEntryAID =
95 htimerRoot_set_expire(
96 &objectEntryAID->htimUnicast.commonNode,
98 //insert new timer to root htimer node
99 htimerRoot_add(objectEntry,
100 &objectEntryAID->htimUnicast.commonNode);
101 debug(2, 10) ("htimerUnicastCommon: root updated, wakeup\n");
102 //wake-up sending thread to process event
103 ORTEDomainWakeUpSendingThread(objectEntry);
109 htimerUnicastCommon_run_expired(ORTEDomain *d,
110 ObjectEntryAID *objectEntryAID,
111 ul_htim_time_t *pact_time)
113 HTimFncUserNode *timer;
115 pthread_rwlock_t *lock;
117 while ((timer = htimerUnicastCommon_cut_expired(objectEntryAID, pact_time))) {
118 if ((lock = timer->lock)) //after proc. timer->func can be timer freed
119 pthread_rwlock_wrlock(timer->lock);
120 debug(2, 10) ("htimerUnicastCommon: %s\n",
122 retValue = timer->func(d, timer->arg1);
124 pthread_rwlock_unlock(timer->lock);
125 if (retValue == 2) //object deleted
128 htimerUnicastCommon_update_root_timer(&d->objectEntry, objectEntryAID);
131 /*****************************************************************************/
132 UL_HTIMER_IMP(htimerUnicastSendMetatraffic, \
135 htimUnicast.sendMetatraffic, \
139 htimerUnicastSendMetatraffic_update_root_timer(ObjectEntry *objectEntry,
140 ObjectEntryAID *objectEntryAID)
144 //if first item is changed -> update root timer queue
145 if (htimerUnicastSendMetatraffic_first_changed(objectEntryAID)) {
146 //deatach old timer from this queue (if any)
147 htimerRoot_detach(objectEntry,
148 &objectEntryAID->htimUnicast.sendMetatrafficNode);
149 if (htimerUnicastSendMetatraffic_next_expire(objectEntryAID, &nextExpire) != 0) {
151 objectEntryAID->htimUnicast.sendMetatrafficNode.func =
152 htimerUnicastSendMetatraffic_run_expired;
153 objectEntryAID->htimUnicast.sendMetatrafficNode.objectEntryAID =
155 htimerRoot_set_expire(
156 &objectEntryAID->htimUnicast.sendMetatrafficNode,
158 //insert new timer to root htimer node
159 htimerRoot_add(objectEntry,
160 &objectEntryAID->htimUnicast.sendMetatrafficNode);
161 debug(2, 10) ("htimerUnicastMetatraffic: root updated, wakeup\n");
162 //wake-up sending thread to process event
163 ORTEDomainWakeUpSendingThread(objectEntry);
169 htimerUnicastSendMetatraffic_run_expired(ORTEDomain *d,
170 ObjectEntryAID *objectEntryAID,
171 ul_htim_time_t *pact_time)
173 HTimFncUserNode *timer;
176 while ((timer = htimerUnicastSendMetatraffic_cut_expired(objectEntryAID, pact_time))) {
178 pthread_rwlock_wrlock(timer->lock);
179 debug(2, 10) ("htimerUnicastMetatraffic: %s\n",
181 retValue = timer->func(d, timer->arg1);
182 while (d->taskSend.mb.needSend) {
183 ORTESendData(d, objectEntryAID, ORTE_TRUE);
184 timer->func(d, timer->arg1);
187 pthread_rwlock_unlock(timer->lock);
189 htimerUnicastSendMetatraffic_update_root_timer(&d->objectEntry, objectEntryAID);
190 if (d->taskSend.mb.cdrCodec.wptr > RTPS_HEADER_LENGTH) {
191 ORTESendData(d, objectEntryAID, ORTE_TRUE);
195 /*****************************************************************************/
196 UL_HTIMER_IMP(htimerUnicastSendUserData, \
199 htimUnicast.sendUserData, \
203 htimerUnicastSendUserData_update_root_timer(ObjectEntry *objectEntry,
204 ObjectEntryAID *objectEntryAID)
208 //if first item is changed -> update root timer queue
209 if (htimerUnicastSendUserData_first_changed(objectEntryAID)) {
210 //deatach old timer from this queue (if any)
211 htimerRoot_detach(objectEntry,
212 &objectEntryAID->htimUnicast.sendUserDataNode);
213 if (htimerUnicastSendUserData_next_expire(objectEntryAID, &nextExpire) != 0) {
215 objectEntryAID->htimUnicast.sendUserDataNode.func =
216 htimerUnicastSendUserData_run_expired;
217 objectEntryAID->htimUnicast.sendUserDataNode.objectEntryAID =
219 htimerRoot_set_expire(
220 &objectEntryAID->htimUnicast.sendUserDataNode,
222 //insert new timer to root htimer node
223 htimerRoot_add(objectEntry,
224 &objectEntryAID->htimUnicast.sendUserDataNode);
225 debug(2, 10) ("htimerUnicastUserdata: root updated, wakeup\n");
226 //wake-up sending thread to process event
227 ORTEDomainWakeUpSendingThread(objectEntry);
233 htimerUnicastSendUserData_run_expired(ORTEDomain *d,
234 ObjectEntryAID *objectEntryAID,
235 ul_htim_time_t *pact_time)
237 HTimFncUserNode *timer;
240 while ((timer = htimerUnicastSendUserData_cut_expired(objectEntryAID, pact_time))) {
242 pthread_rwlock_wrlock(timer->lock);
243 retValue = timer->func(d, timer->arg1);
244 while (d->taskSend.mb.needSend) {
245 ORTESendData(d, objectEntryAID, ORTE_FALSE);
246 timer->func(d, timer->arg1);
249 pthread_rwlock_unlock(timer->lock);
251 htimerUnicastSendUserData_update_root_timer(&d->objectEntry, objectEntryAID);
252 if (d->taskSend.mb.cdrCodec.wptr > RTPS_HEADER_LENGTH) {
253 ORTESendData(d, objectEntryAID, ORTE_FALSE);
257 /*********************************************************************/
259 getActualNtpTime(void)
263 #ifndef CONFIG_ORTE_RT
266 gettimeofday(&time, NULL);
267 NtpTimeAssembFromUs(result, time.tv_sec, time.tv_usec);
268 NtpTimeAssembFromUs(result, time.tv_sec, time.tv_usec);
270 struct timespec time;
272 clock_gettime(CLOCK_REALTIME, &time);
273 time.tv_nsec /= 1000; //conver to us
274 NtpTimeAssembFromUs(result, time.tv_sec, time.tv_nsec);