Merge lp:~epics-core/epics-base/3.15_libcom_from_cvs_trunk into lp:~epics-core/epics-base/3.15
- 3.15_libcom_from_cvs_trunk
- Merge into 3.15
Status: | Merged |
---|---|
Merged at revision: | 12518 |
Proposed branch: | lp:~epics-core/epics-base/3.15_libcom_from_cvs_trunk |
Merge into: | lp:~epics-core/epics-base/3.15 |
Diff against target: |
1110 lines (+391/-281) (has conflicts) 14 files modified
src/ca/legacy/pcas/generic/casPVI.cc (+3/-2) src/libCom/bucketLib/bucketLib.c (+2/-2) src/libCom/cxxTemplates/README (+1/-23) src/libCom/fdmgr/fdManager.cpp (+5/-8) src/libCom/fdmgr/fdManager.h (+2/-2) src/libCom/misc/aToIPAddr.c (+151/-46) src/libCom/misc/ipAddrToAsciiAsynchronous.cpp (+2/-2) src/libCom/osi/epicsTime.cpp (+53/-53) src/libCom/osi/os/WIN32/osdProcess.c (+63/-77) src/libCom/osi/os/WIN32/osdTime.cpp (+80/-40) src/libCom/osi/os/vxWorks/osdSock.c (+3/-10) src/libCom/osi/osiNTPTime.c (+1/-0) src/libCom/test/blockingSockTest.cpp (+25/-11) src/libCom/test/epicsTimeTest.cpp (+0/-5) Text conflict in src/libCom/test/blockingSockTest.cpp |
To merge this branch: | bzr merge lp:~epics-core/epics-base/3.15_libcom_from_cvs_trunk |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
mdavidsaver | read code and ran tests | Approve | |
Review via email: mp+194399@code.launchpad.net |
Commit message
Description of the change
This is syncing libCom with some easier to merge elements of my development in an branch deriving from the EPICS cvs trunk. Here is a quick summary of the changes.
o fixed compile errors in, and proper diagnostic from, casPVI.cc
o suprressed some compile time warnings in bucketLib.c
o cleaned up cxx templates README
o removed use of tsMinMax from libCom in favor of the standard library
(calls to tsMinMax still exist in other components in base, but they are being removed)
o removed sharable library export of certain private member functions from class fdManager
o fixed aToIPAddr to correctly lookup all of the different IP address string types on all OS types independent of the OS interfae variations
o removed use of inet_aton from vxWorks implementation of hostToIPAddr
o this function is for converting a host name to an ip address _only_
o the aToIPAddr wrapper is supposed to do the dotted ip ascii string to ip address structure conversion independent of OS spoecific interface variations, when it works correctly
o fixed some spelling issues in comments
o added additional optimizations for processors w/o floating point ALU to addNanoSec in epicsTime
o removed tabs and junk comments from win32 osdProcess.c
o moved PLL update in win32 osdTime.c from timer to a dedicated thread
o added missing epicsExportShared symbols define to osiNTPTime.c
o fixed server ctor should not modify arguments of its caller in blockingSockTest
o removed sunpro specific ifdef nolonger needed from epicsTimeTest.cpp
- 12452. By Jeff Hill
-
oops, variable used to be unsigned; changed to signed constant
- 12453. By Jeff Hill
-
fixed ms compiler build
- 12454. By Andrew Johnson
-
Use epicsUInt types, stdint.h is not found on all platforms
- 12455. By Andrew Johnson
-
Fix typo in macro name
Not that it really matters since only VxWorks and RTEMS actually
compile this file and they don't have shared libraries... - 12456. By Andrew Johnson
-
blockingSockTest: Undo member renames using m_ prefix
Using the m_ prefix to denote class data members is dangerous in
code that has to compile on VxWorks 5.5 (which 3.15 does) because
the net/mbuf.h header contains the following macro definitions:#define m_next mBlkHdr.mNext
#define m_len mBlkHdr.mLen
#define m_data mBlkHdr.mData
#define m_type mBlkHdr.mType
#define m_flags mBlkHdr.mFlags
#define m_nextpkt mBlkHdr.mNextPkt
#define m_act m_nextpkt
#define m_pkthdr mBlkPktHdr
#define m_ext pClBlk
#define m_extBuf m_ext->clNode. pClBuf
#define m_extFreeRtn m_ext->pClFreeRtn
#define m_extSize m_ext->clSize
#define m_extRefCnt m_ext->clRefCnt
#define m_extArg1 m_ext->clFreeArg1
#define m_extArg2 m_ext->clFreeArg2
#define m_extArg3 m_ext->clFreeArg3
#define m_copy(m, o, l) m_copym((m), (o), (l), M_DONTWAIT)
#define m_copym(m, o, l, w) netMblkChainDup(_pNetDpool, (m), (o), (l), (w))
#define m_freem(m) netMblkClChainFree(m)
#define m_free(m) netMblkClFree(m)
#define m_mbufs mNum
#define m_drops mDrops
#define m_wait mWait
#define m_drain mDrain
#define m_mtypes mTypesWhile the names in the original change all appear to be safe, I
don't want us to start using this convention because we will then
have to police commits more closely or risk build failures in the
future when someone who doesn't know about or remember the issue
can't or doesn't try building their code against VxWorks 5.5.I don't particularly like the this-> convention to mark member
names either, but until the VxWorks 5.5 support requirement goes
away the m_ convention is worse. Another common convention of
using a leading underscore is not safe either, those names are
reserved for the C/C++ implementation.
Andrew Johnson (anj) wrote : | # |
mdavidsaver (mdavidsaver) wrote : | # |
> #ifdef __cplusplus
> #include <cstddef>
> using std :: size_t;
> #else
> #include <stddef.h>
> #endif
I don't see any benefit to language conditional includes, and the potential for subtle ABI problems.
Also, IMO "using" entries in public headers which pull names into the global namespace are a bad policy. Don't polute the global namespace.
This case is especially puzzling as <cstddef> contains the inverse (less the GCC macros).
> #include <stddef.h>
> namespace std {using ::size_t;}
mdavidsaver (mdavidsaver) wrote : | # |
o fixed aToIPAddr to correctly lookup all of the different IP addresses string types on all OS types
independent of the OS interfae variations
Did you identified some inconsistency in aToIPAddr()? On which OS(s)? Please add test cases to epicsSockResolv
Andrew Johnson (anj) wrote : | # |
Michael, I think Jeff's changes to aToIPAddr() are just re-implementing the fix that you originally worked on in a way that doesn't push work down into the individual osdSock.c hostToIPAddr() routines. Since Jeff wrote the original I'm willing to let him reshape the fix since he knows how the code was supposed to work. This version does pass all the tests that you created.
- 12457. By Andrew Johnson
-
Reverted changes to epicsTime.h and epicsThread.h
Andrew Johnson (anj) wrote : | # |
I reverted the changes to epicsTime.h and epicsThread.h, and I think the result is now suitable for merging. I will aim to do that at the Codeathon next week as long as nobody objects in the meantime.
mdavidsaver (mdavidsaver) wrote : | # |
The remaining changes seem ok.
Preview Diff
1 | === modified file 'src/ca/legacy/pcas/generic/casPVI.cc' |
2 | --- src/ca/legacy/pcas/generic/casPVI.cc 2012-10-11 16:28:28 +0000 |
3 | +++ src/ca/legacy/pcas/generic/casPVI.cc 2014-08-19 03:55:55 +0000 |
4 | @@ -211,9 +211,10 @@ |
5 | } |
6 | } |
7 | else { |
8 | - errMessage ( S_cas_badType, |
9 | + errPrintf ( S_cas_badType, __FILE__, __LINE__, |
10 | "application type \"enums\" string conversion" |
11 | - " table for enumerated PV isnt a string type?" ); |
12 | + " table for enumerated PV \"%s\" isnt a string type?", |
13 | + getName() ); |
14 | } |
15 | } |
16 | else if ( resp.dimension() == 1 ) { |
17 | |
18 | === modified file 'src/libCom/bucketLib/bucketLib.c' |
19 | --- src/libCom/bucketLib/bucketLib.c 2013-11-20 00:42:45 +0000 |
20 | +++ src/libCom/bucketLib/bucketLib.c 2014-08-19 03:55:55 +0000 |
21 | @@ -144,7 +144,7 @@ |
22 | */ |
23 | static BUCKETID bucketUnsignedHash (BUCKET *pb, const void *pId) |
24 | { |
25 | - const unsigned *pUId = pId; |
26 | + const unsigned *pUId = (const unsigned *) pId; |
27 | unsigned src; |
28 | BUCKETID hashid; |
29 | |
30 | @@ -194,7 +194,7 @@ |
31 | */ |
32 | static BUCKETID bucketStringHash (BUCKET *pb, const void *pId) |
33 | { |
34 | - const char *pStr = pId; |
35 | + const char *pStr = (const char *) pId; |
36 | BUCKETID hashid; |
37 | unsigned i; |
38 | |
39 | |
40 | === modified file 'src/libCom/cxxTemplates/README' |
41 | --- src/libCom/cxxTemplates/README 2000-09-11 16:15:29 +0000 |
42 | +++ src/libCom/cxxTemplates/README 2014-08-19 03:55:55 +0000 |
43 | @@ -30,28 +30,6 @@ |
44 | from class "ID" (the hash table key type) and also derive from |
45 | tsSLNode<T>. |
46 | |
47 | -So far, the only confusion I have run into with templates has been: |
48 | - |
49 | -1) strange compiler messages - unrelated to cause of course - |
50 | -when I get the class declaration order wrong (so that the |
51 | -compiler has trouble instantiating the template). |
52 | - |
53 | -2) sun pro/dec/att compilers use a template database and |
54 | -gnu/msvc++ compilers use explicit template instantiation. |
55 | -Therefore blocks of code of this sort are required: |
56 | - |
57 | -#include "resourceLib.h" // template def |
58 | -#include "resourceLib.cc" // template functions (that are not inline) |
59 | -#if defined (EXPL_TEMPL) |
60 | - // |
61 | - // From Stroustrups's "The C++ Programming Language" |
62 | - // Appendix A: r.14.9 |
63 | - // |
64 | - // This explicitly instantiates the template class's member |
65 | - // functions into "templInst.o" |
66 | - // |
67 | - template class resTable<fred,uintId>; |
68 | - template class resTable<jane,stringId>; |
69 | -#endif |
70 | + |
71 | |
72 | |
73 | |
74 | === modified file 'src/libCom/fdmgr/fdManager.cpp' |
75 | --- src/libCom/fdmgr/fdManager.cpp 2012-07-19 19:59:55 +0000 |
76 | +++ src/libCom/fdmgr/fdManager.cpp 2014-08-19 03:55:55 +0000 |
77 | @@ -21,20 +21,17 @@ |
78 | // 1) This library is not thread safe |
79 | // |
80 | |
81 | -// |
82 | -// ANSI C |
83 | -// |
84 | -#include <errno.h> |
85 | -#include <string.h> |
86 | +#include <algorithm> |
87 | |
88 | #define instantiateRecourceLib |
89 | #define epicsExportSharedSymbols |
90 | #include "epicsAssert.h" |
91 | #include "epicsThread.h" |
92 | -#include "tsMinMax.h" |
93 | #include "fdManager.h" |
94 | #include "locationException.h" |
95 | |
96 | +using std :: max; |
97 | + |
98 | epicsShareDef fdManager fileDescriptorManager; |
99 | |
100 | const unsigned mSecPerSec = 1000u; |
101 | @@ -261,9 +258,9 @@ |
102 | // |
103 | // fdManager::installReg () |
104 | // |
105 | -epicsShareFunc void fdManager::installReg (fdReg ®) |
106 | +void fdManager::installReg (fdReg ®) |
107 | { |
108 | - this->maxFD = tsMax ( this->maxFD, reg.getFD()+1 ); |
109 | + this->maxFD = max ( this->maxFD, reg.getFD()+1 ); |
110 | // Most applications will find that its important to push here to |
111 | // the front of the list so that transient writes get executed |
112 | // first allowing incoming read protocol to find that outgoing |
113 | |
114 | === modified file 'src/libCom/fdmgr/fdManager.h' |
115 | --- src/libCom/fdmgr/fdManager.h 2012-07-19 19:59:55 +0000 |
116 | +++ src/libCom/fdmgr/fdManager.h 2014-08-19 03:55:55 +0000 |
117 | @@ -104,8 +104,8 @@ |
118 | fdReg * pCBReg; |
119 | void reschedule (); |
120 | double quantum (); |
121 | - epicsShareFunc void installReg (fdReg ®); |
122 | - epicsShareFunc void removeReg (fdReg ®); |
123 | + void installReg (fdReg ®); |
124 | + void removeReg (fdReg ®); |
125 | void lazyInitTimerQueue (); |
126 | fdManager ( const fdManager & ); |
127 | fdManager & operator = ( const fdManager & ); |
128 | |
129 | === modified file 'src/libCom/misc/aToIPAddr.c' |
130 | --- src/libCom/misc/aToIPAddr.c 2013-06-07 23:08:38 +0000 |
131 | +++ src/libCom/misc/aToIPAddr.c 2014-08-19 03:55:55 +0000 |
132 | @@ -1,8 +1,8 @@ |
133 | /*************************************************************************\ |
134 | +* Copyright (c) 2013 LANS LLC, as Operator of |
135 | +* Los Alamos National Laboratory. |
136 | * Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne |
137 | * National Laboratory. |
138 | -* Copyright (c) 2002 The Regents of the University of California, as |
139 | -* Operator of Los Alamos National Laboratory. |
140 | * EPICS BASE is distributed subject to a Software License Agreement found |
141 | * in file LICENSE that is included with this distribution. |
142 | \*************************************************************************/ |
143 | @@ -15,21 +15,52 @@ |
144 | #include <string.h> |
145 | |
146 | #define epicsExportSharedSymbols |
147 | +#include "epicsTypes.h" |
148 | #include "osiSock.h" |
149 | -#include "epicsStdlib.h" |
150 | + |
151 | +#ifndef NELEMENTS |
152 | +#define NELEMENTS(A) (sizeof(A)/sizeof(A[0])) |
153 | +#endif /*NELEMENTS*/ |
154 | + |
155 | +/* |
156 | + * addrArrayToUL () |
157 | + */ |
158 | +static int addrArrayToUL ( const unsigned *pAddr, |
159 | + unsigned nElements, struct in_addr *pIpAddr ) |
160 | +{ |
161 | + unsigned i; |
162 | + epicsUInt32 addr = 0ul; |
163 | + |
164 | + for ( i=0u; i < nElements; i++ ) { |
165 | + if ( pAddr[i] > 0xff ) { |
166 | + return -1; |
167 | + } |
168 | + addr <<= 8; |
169 | + addr |= ( epicsUInt32 ) pAddr[i]; |
170 | + } |
171 | + pIpAddr->s_addr = htonl ( addr ); |
172 | + |
173 | + return 0; |
174 | +} |
175 | |
176 | /* |
177 | * initIPAddr() |
178 | * !! ipAddr should be passed in in network byte order !! |
179 | * !! port is passed in in host byte order !! |
180 | */ |
181 | -static int initIPAddr (struct in_addr ipAddr, unsigned short port, |
182 | - struct sockaddr_in *pIP) |
183 | +static int initIPAddr ( struct in_addr ipAddr, unsigned port, |
184 | + struct sockaddr_in *pIP ) |
185 | { |
186 | - memset(pIP, '\0', sizeof(*pIP)); |
187 | - pIP->sin_family = AF_INET; |
188 | - pIP->sin_port = htons(port); |
189 | - pIP->sin_addr = ipAddr; |
190 | + if ( port > 0xffff ) { |
191 | + return -1; |
192 | + } |
193 | + { |
194 | + epicsUInt16 port_16 = (epicsUInt16) port; |
195 | + memset (pIP, '\0', sizeof(*pIP)); |
196 | + pIP->sin_family = AF_INET; |
197 | + pIP->sin_port = htons(port_16); |
198 | + pIP->sin_addr = ipAddr; |
199 | + } |
200 | return 0; |
201 | } |
202 | |
203 | @@ -42,47 +73,121 @@ |
204 | * |
205 | * Sets the port number to "defaultPort" only if |
206 | * "pAddrString" does not contain an address of the form |
207 | - * "n.n.n.n:p" |
208 | + * "n.n.n.n:p or host:p" |
209 | */ |
210 | -epicsShareFunc int epicsShareAPI |
211 | -aToIPAddr(const char *pAddrString, unsigned short defaultPort, |
212 | - struct sockaddr_in *pIP) |
213 | +epicsShareFunc int epicsShareAPI |
214 | +aToIPAddr( const char *pAddrString, unsigned short defaultPort, |
215 | + struct sockaddr_in *pIP ) |
216 | { |
217 | int status; |
218 | - char hostName[512]; /* !! change n elements here requires change in format below !! */ |
219 | - unsigned int port; |
220 | - unsigned long numaddr; |
221 | + unsigned addr[4]; |
222 | + unsigned long rawAddr; |
223 | + /* |
224 | + * !! change n elements here requires change in format below !! |
225 | + */ |
226 | + char hostName[512]; |
227 | + char dummy[8]; |
228 | + unsigned port; |
229 | struct in_addr ina; |
230 | |
231 | /* |
232 | - * Scan for a port number |
233 | - */ |
234 | - status = sscanf( pAddrString, " %511[^:]:%u", hostName, &port ); |
235 | - if ( status == 0 ) { |
236 | - return -1; |
237 | - } |
238 | - if ( status == 1 ) { |
239 | - port = defaultPort; |
240 | - } |
241 | - else if (status == 2 && port > 65535) { |
242 | - return -1; |
243 | - } |
244 | - |
245 | - /* |
246 | - * Look for a valid host name or dotted quad |
247 | - */ |
248 | - status = hostToIPAddr( hostName, &ina ); |
249 | - if ( status == 0 ) { |
250 | - return initIPAddr( ina, port, pIP ); |
251 | - } |
252 | - |
253 | - /* |
254 | - * Try the IP address as a decimal integer |
255 | - */ |
256 | - if ( epicsParseULong( hostName, &numaddr, 10, NULL ) ) { |
257 | - return -1; |
258 | - } |
259 | - |
260 | - ina.s_addr = htonl( numaddr ); |
261 | - return initIPAddr( ina, port, pIP ); |
262 | + * dotted ip addresses |
263 | + */ |
264 | + status = sscanf ( pAddrString, " %u . %u . %u . %u %7s ", |
265 | + addr, addr+1u, addr+2u, addr+3u, dummy ); |
266 | + if ( status == 4 ) { |
267 | + if ( addrArrayToUL ( addr, NELEMENTS ( addr ), & ina ) < 0 ) { |
268 | + return -1; |
269 | + } |
270 | + port = defaultPort; |
271 | + return initIPAddr ( ina, port, pIP ); |
272 | + } |
273 | + |
274 | + /* |
275 | + * dotted ip addresses and port |
276 | + */ |
277 | + status = sscanf ( pAddrString, " %u . %u . %u . %u : %u %7s", |
278 | + addr, addr+1u, addr+2u, addr+3u, &port, dummy ); |
279 | + if ( status >= 5 ) { |
280 | + if ( status > 5 ) { |
281 | + /* |
282 | + * valid at the start but detritus on the end |
283 | + */ |
284 | + return -1; |
285 | + } |
286 | + if ( addrArrayToUL ( addr, NELEMENTS ( addr ), &ina ) < 0 ) { |
287 | + return -1; |
288 | + } |
289 | + return initIPAddr ( ina, port, pIP ); |
290 | + } |
291 | + |
292 | + /* |
293 | + * IP address as a raw number |
294 | + */ |
295 | + status = sscanf ( pAddrString, " %lu %7s ", &rawAddr, dummy ); |
296 | + if ( status == 1 ) { |
297 | + if ( rawAddr > 0xffffffff ) { |
298 | + return -1; |
299 | + } |
300 | + port = defaultPort; |
301 | + { |
302 | + epicsUInt32 rawAddr_32 = ( epicsUInt32 ) rawAddr; |
303 | + ina.s_addr = htonl ( rawAddr_32 ); |
304 | + return initIPAddr ( ina, port, pIP ); |
305 | + } |
306 | + } |
307 | + |
308 | + /* |
309 | + * IP address as a raw number, and port |
310 | + */ |
311 | + status = sscanf ( pAddrString, " %lu : %u %7s ", &rawAddr, &port, dummy ); |
312 | + if ( status >= 2 ) { |
313 | + if ( status > 2 ) { |
314 | + /* |
315 | + * valid at the start but detritus on the end |
316 | + */ |
317 | + return -1; |
318 | + } |
319 | + if ( rawAddr > 0xffffffff ) { |
320 | + return -1; |
321 | + } |
322 | + { |
323 | + epicsUInt32 rawAddr_32 = ( epicsUInt32 ) rawAddr; |
324 | + ina.s_addr = htonl ( rawAddr_32 ); |
325 | + return initIPAddr ( ina, port, pIP ); |
326 | + } |
327 | + } |
328 | + |
329 | + |
330 | + /* |
331 | + * host name string |
332 | + */ |
333 | + status = sscanf ( pAddrString, " %511[^:] %s ", hostName, dummy ); |
334 | + if ( status == 1 ) { |
335 | + port = defaultPort; |
336 | + status = hostToIPAddr ( hostName, &ina ); |
337 | + if ( status == 0 ) { |
338 | + return initIPAddr ( ina, port, pIP ); |
339 | + } |
340 | + } |
341 | + |
342 | + /* |
343 | + * host name string, and port |
344 | + */ |
345 | + status = sscanf ( pAddrString, " %511[^:] : %u %s ", hostName, |
346 | + &port, dummy ); |
347 | + if ( status >= 2 ) { |
348 | + if ( status > 2 ) { |
349 | + /* |
350 | + * valid at the start but detritus on the end |
351 | + */ |
352 | + return -1; |
353 | + } |
354 | + status = hostToIPAddr ( hostName, &ina ); |
355 | + if ( status == 0 ) { |
356 | + return initIPAddr ( ina, port, pIP ); |
357 | + } |
358 | + } |
359 | + |
360 | + return -1; |
361 | } |
362 | |
363 | === modified file 'src/libCom/misc/ipAddrToAsciiAsynchronous.cpp' |
364 | --- src/libCom/misc/ipAddrToAsciiAsynchronous.cpp 2014-02-07 20:13:12 +0000 |
365 | +++ src/libCom/misc/ipAddrToAsciiAsynchronous.cpp 2014-08-19 03:55:55 +0000 |
366 | @@ -25,7 +25,7 @@ |
367 | #include <string> |
368 | #include <climits> |
369 | #include <stdexcept> |
370 | -#include <stdio.h> |
371 | +#include <cstdio> |
372 | |
373 | #define epicsExportSharedSymbols |
374 | #include "ipAddrToAsciiAsynchronous.h" |
375 | @@ -206,7 +206,7 @@ |
376 | this->thread.exitWait (); |
377 | } |
378 | |
379 | -// for now its probably sufficent to allocate one |
380 | +// for now its probably sufficient to allocate one |
381 | // DNS transaction thread for all codes sharing |
382 | // the same process that need DNS services but we |
383 | // leave our options open for the future |
384 | |
385 | === modified file 'src/libCom/osi/epicsTime.cpp' |
386 | --- src/libCom/osi/epicsTime.cpp 2014-03-13 20:04:31 +0000 |
387 | +++ src/libCom/osi/epicsTime.cpp 2014-08-19 03:55:55 +0000 |
388 | @@ -1,8 +1,10 @@ |
389 | /*************************************************************************\ |
390 | +* Copyright (c) 2011 LANS LLC, as Operator of |
391 | +* Los Alamos National Laboratory. |
392 | +* Copyright (c) 2002 The Regents of the University of California, as |
393 | +* Operator of Los Alamos National Laboratory. |
394 | * Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne |
395 | * National Laboratory. |
396 | -* Copyright (c) 2002 The Regents of the University of California, as |
397 | -* Operator of Los Alamos National Laboratory. |
398 | * EPICS BASE is distributed subject to a Software License Agreement found |
399 | * in file LICENSE that is included with this distribution. |
400 | \*************************************************************************/ |
401 | @@ -58,8 +60,12 @@ |
402 | // |
403 | // epicsTime (const unsigned long secIn, const unsigned long nSecIn) |
404 | // |
405 | -inline epicsTime::epicsTime (const unsigned long secIn, const unsigned long nSecIn) : |
406 | - secPastEpoch ( nSecIn / nSecPerSec + secIn ), nSec ( nSecIn % nSecPerSec ) {} |
407 | +inline epicsTime::epicsTime (const unsigned long secIn, |
408 | + const unsigned long nSecIn) : |
409 | + secPastEpoch ( nSecIn / nSecPerSec + secIn ), |
410 | + nSec ( nSecIn % nSecPerSec ) |
411 | +{ |
412 | +} |
413 | |
414 | // |
415 | // epicsTimeLoadTimeInit |
416 | @@ -109,51 +115,45 @@ |
417 | // |
418 | // epicsTime::addNanoSec () |
419 | // |
420 | -// many of the UNIX timestamp formats have nano sec stored as a long |
421 | +// The nano-second field of several of the the UNIX time stamp formats |
422 | +// field is stored in the C type "long". |
423 | // |
424 | -void epicsTime::addNanoSec (long nSecAdj) |
425 | +void epicsTime :: addNanoSec ( long nSecAdj ) |
426 | { |
427 | - // After optimizing this function we now have a larger |
428 | - // code which uses only unsigned integer arithmetic. |
429 | - // This is for the benefit of embedded cpu's lacking |
430 | - // a hardware floating point coprocessor at the |
431 | - // expense of some additional code to maintain. |
432 | - // joh 14-11-2012 |
433 | + // |
434 | + // After optimizing this function we now have a larger code which |
435 | + // uses only unsigned integer, and not floating point, arithmetic. |
436 | + // This change benefits embedded CPU's lacking a floating point |
437 | + // co-processor at the expense of some additional code to maintain. |
438 | + // |
439 | + // We hope that all CPU's we run on provide at least an integer |
440 | + // divide instruction which should enable this implementation |
441 | + // to be more efficient than implementations based on branching; |
442 | + // this is presuming that we will run on pipelined architectures. |
443 | + // |
444 | + // Overflow and underflow is expected; in the future we might |
445 | + // operate close to, the modulo of, the EPICS epic. |
446 | + // |
447 | + // We are depending on the normalize operation in the private |
448 | + // constructor used below. |
449 | + // |
450 | + // joh 11-04-2012 |
451 | + // |
452 | if ( nSecAdj >= 0 ) { |
453 | - unsigned long nSecOffsetLong = |
454 | - static_cast < unsigned long > ( nSecAdj ); |
455 | - while ( nSecOffsetLong >= nSecPerSec ) { |
456 | - this->secPastEpoch++; // overflow expected |
457 | - nSecOffsetLong -= nSecPerSec; |
458 | - } |
459 | - const epicsUInt32 nSecOffset = |
460 | - static_cast < epicsUInt32 > ( nSecOffsetLong ); |
461 | - epicsUInt32 nSecPerSecRemaining = nSecPerSec - nSecOffset; |
462 | - if ( this->nSec >= nSecPerSecRemaining ) { |
463 | - this->secPastEpoch++; // overflow expected |
464 | - this->nSec -= nSecPerSecRemaining; |
465 | - } |
466 | - else { |
467 | - this->nSec += nSecOffset; |
468 | - } |
469 | + const unsigned long nSecPlus = |
470 | + static_cast <unsigned long> ( nSecAdj ); |
471 | + const unsigned long nSecPlusAdj = nSecPlus % nSecPerSec; |
472 | + const unsigned long secPlusAdj = nSecPlus / nSecPerSec; |
473 | + *this = epicsTime ( this->secPastEpoch+secPlusAdj, |
474 | + this->nSec+nSecPlusAdj ); |
475 | } |
476 | else { |
477 | - unsigned long nSecOffsetLong = |
478 | - static_cast <unsigned long> ( -nSecAdj ); |
479 | - while ( nSecOffsetLong >= nSecPerSec ) { |
480 | - this->secPastEpoch--; // underflow expected |
481 | - nSecOffsetLong -= nSecPerSec; |
482 | - } |
483 | - const epicsUInt32 nSecOffset = |
484 | - static_cast < epicsUInt32 > ( nSecOffsetLong ); |
485 | - if ( this->nSec >= nSecOffset ) { |
486 | - this->nSec -= nSecOffset; |
487 | - } |
488 | - else { |
489 | - // borrow |
490 | - this->secPastEpoch--; // underflow expected |
491 | - this->nSec += nSecPerSec - nSecOffset; |
492 | - } |
493 | + const unsigned long nSecMinus = |
494 | + static_cast <unsigned long> ( -nSecAdj ); |
495 | + const unsigned long nSecMinusAdj = nSecMinus % nSecPerSec; |
496 | + const unsigned long secMinusAdj = nSecMinus / nSecPerSec; |
497 | + *this = epicsTime ( this->secPastEpoch - secMinusAdj - 1u, |
498 | + this->nSec + nSecPerSec - nSecMinusAdj ); |
499 | } |
500 | } |
501 | |
502 | @@ -368,8 +368,8 @@ |
503 | time_t_wrapper ansiTimeTicks; |
504 | |
505 | ansiTimeTicks = *this; |
506 | - // On Posix systems timeval :: tv_sec is a time_t so this can be |
507 | - // a direct assignement. On other systems I dont know that we can |
508 | + // On Posix systems timeval :: tv_sec is a time_t so this can be |
509 | + // a direct assignment. On other systems I dont know that we can |
510 | // guarantee that time_t and timeval :: tv_sec will have the |
511 | // same epoch or have the same scaling factor to discrete seconds. |
512 | // For example, on windows time_t changed recently to a 64 bit |
513 | @@ -387,8 +387,8 @@ |
514 | epicsTime::epicsTime (const struct timeval &ts) |
515 | { |
516 | time_t_wrapper ansiTimeTicks; |
517 | - // On Posix systems timeval :: tv_sec is a time_t so this can be |
518 | - // a direct assignement. On other systems I dont know that we can |
519 | + // On Posix systems timeval :: tv_sec is a time_t so this can be |
520 | + // a direct assignment. On other systems I dont know that we can |
521 | // guarantee that time_t and timeval :: tv_sec will have the |
522 | // same epoch or have the same scaling factor to discrete seconds. |
523 | // For example, on windows time_t changed recently to a 64 bit |
524 | @@ -438,11 +438,11 @@ |
525 | } |
526 | epicsTimeStamp ts; |
527 | // |
528 | - // trucation by design |
529 | + // truncation by design |
530 | // ------------------- |
531 | - // epicsTime::secPastEpoch is based on ulong and has much greater range |
532 | - // on 64 bit hosts than the orginal epicsTimeStamp::secPastEpoch. The |
533 | - // epicsTimeStamp::secPastEpoch is based on epicsUInt32 so that it will |
534 | + // epicsTime::secPastEpoch is based on ulong and has much greater range |
535 | + // on 64 bit hosts than the original epicsTimeStamp::secPastEpoch. The |
536 | + // epicsTimeStamp::secPastEpoch is based on epicsUInt32 so that it will |
537 | // match the original network protocol. Of course one can anticipate |
538 | // that eventually, a epicsUInt64 based network time stamp will be |
539 | // introduced when 64 bit architectures are more ubiquitous. |
540 | @@ -655,7 +655,7 @@ |
541 | } |
542 | |
543 | if ( level > 1 ) { |
544 | - // this also supresses the "defined, but not used" |
545 | + // this also suppresses the "defined, but not used" |
546 | // warning message |
547 | printf ( "epicsTime: revision \"%s\"\n", |
548 | pEpicsTimeVersion ); |
549 | |
550 | === modified file 'src/libCom/osi/os/WIN32/osdProcess.c' |
551 | --- src/libCom/osi/os/WIN32/osdProcess.c 2010-10-05 19:27:37 +0000 |
552 | +++ src/libCom/osi/os/WIN32/osdProcess.c 2014-08-19 03:55:55 +0000 |
553 | @@ -64,90 +64,76 @@ |
554 | startupInfo.wShowWindow = SW_SHOWMINNOACTIVE; |
555 | |
556 | status = CreateProcess ( |
557 | - NULL, /* pointer to name of executable module (not required if command line is specified) */ |
558 | - (char *) pBaseExecutableName, /* pointer to command line string */ |
559 | - NULL, /* pointer to process security attributes */ |
560 | - NULL, /* pointer to thread security attributes */ |
561 | - FALSE, /* handle inheritance flag */ |
562 | - CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS, /* creation flags */ |
563 | - NULL, /* pointer to new environment block (defaults to caller's environement) */ |
564 | - NULL, /* pointer to current directory name (defaults to caller's current directory) */ |
565 | - &startupInfo, /* pointer to STARTUPINFO */ |
566 | - &processInfo /* pointer to PROCESS_INFORMATION */ |
567 | - ); |
568 | - if ( status == 0 ) { |
569 | - DWORD W32status; |
570 | - LPVOID errStrMsgBuf; |
571 | - LPVOID complteMsgBuf; |
572 | - |
573 | - W32status = FormatMessage ( |
574 | - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, |
575 | - NULL, |
576 | - GetLastError (), |
577 | - MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ |
578 | - (LPTSTR) &errStrMsgBuf, |
579 | - 0, |
580 | - NULL |
581 | - ); |
582 | - |
583 | - if ( W32status ) { |
584 | - char *pFmtArgs[6]; |
585 | + NULL, /* pointer to name of executable module (not required if command line is specified) */ |
586 | + (char *) pBaseExecutableName, /* pointer to command line string */ |
587 | + NULL, /* pointer to process security attributes */ |
588 | + NULL, /* pointer to thread security attributes */ |
589 | + FALSE, /* handle inheritance flag */ |
590 | + CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS, /* creation flags */ |
591 | + NULL, /* pointer to new environment block (defaults to caller's environement) */ |
592 | + NULL, /* pointer to current directory name (defaults to caller's current directory) */ |
593 | + &startupInfo, /* pointer to STARTUPINFO */ |
594 | + &processInfo /* pointer to PROCESS_INFORMATION */ |
595 | + ); |
596 | + if ( status == 0 ) { |
597 | + DWORD W32status; |
598 | + LPVOID errStrMsgBuf; |
599 | + LPVOID complteMsgBuf; |
600 | + |
601 | + W32status = FormatMessage ( |
602 | + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, |
603 | + NULL, |
604 | + GetLastError (), |
605 | + MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ |
606 | + (LPTSTR) &errStrMsgBuf, |
607 | + 0, |
608 | + NULL |
609 | + ); |
610 | + |
611 | + if ( W32status ) { |
612 | + char *pFmtArgs[6]; |
613 | pFmtArgs[0] = "Failed to start executable -"; |
614 | pFmtArgs[1] = (char *) pBaseExecutableName; |
615 | pFmtArgs[2] = errStrMsgBuf; |
616 | pFmtArgs[3] = "Changes may be required in your \"path\" environment variable."; |
617 | pFmtArgs[4] = "PATH = "; |
618 | pFmtArgs[5] = getenv ("path"); |
619 | - if ( pFmtArgs[5] == NULL ) { |
620 | - pFmtArgs[5] = "<empty string>"; |
621 | - } |
622 | - |
623 | - W32status = FormatMessage( |
624 | - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING | |
625 | - FORMAT_MESSAGE_ARGUMENT_ARRAY | 80, |
626 | - "%1 \"%2\". %3 %4 %5 \"%6\"", |
627 | - 0, |
628 | - MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ |
629 | - (LPTSTR) &complteMsgBuf, |
630 | - 0, |
631 | - pFmtArgs |
632 | - ); |
633 | - if (W32status) { |
634 | - /* Display the string. */ |
635 | - MessageBox (NULL, complteMsgBuf, "Configuration Problem", |
636 | - MB_OK | MB_ICONINFORMATION); |
637 | - LocalFree (complteMsgBuf); |
638 | - } |
639 | - else { |
640 | - /* Display the string. */ |
641 | - MessageBox (NULL, errStrMsgBuf, "Failed to start executable", |
642 | - MB_OK | MB_ICONINFORMATION); |
643 | - } |
644 | - |
645 | - /* Free the buffer. */ |
646 | - LocalFree (errStrMsgBuf); |
647 | - } |
648 | - else { |
649 | - errlogPrintf ("!!WARNING!!\n"); |
650 | - errlogPrintf ("Unable to locate executable \"%s\".\n", pBaseExecutableName); |
651 | - errlogPrintf ("You may need to modify your environment.\n"); |
652 | - } |
653 | + if ( pFmtArgs[5] == NULL ) { |
654 | + pFmtArgs[5] = "<empty string>"; |
655 | + } |
656 | + |
657 | + W32status = FormatMessage( |
658 | + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING | |
659 | + FORMAT_MESSAGE_ARGUMENT_ARRAY | 80, |
660 | + "%1 \"%2\". %3 %4 %5 \"%6\"", |
661 | + 0, |
662 | + MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ |
663 | + (LPTSTR) &complteMsgBuf, |
664 | + 0, |
665 | + pFmtArgs |
666 | + ); |
667 | + if (W32status) { |
668 | + /* Display the string. */ |
669 | + MessageBox (NULL, complteMsgBuf, "Configuration Problem", |
670 | + MB_OK | MB_ICONINFORMATION); |
671 | + LocalFree (complteMsgBuf); |
672 | + } |
673 | + else { |
674 | + /* Display the string. */ |
675 | + MessageBox (NULL, errStrMsgBuf, "Failed to start executable", |
676 | + MB_OK | MB_ICONINFORMATION); |
677 | + } |
678 | + |
679 | + /* Free the buffer. */ |
680 | + LocalFree (errStrMsgBuf); |
681 | + } |
682 | + else { |
683 | + errlogPrintf ("!!WARNING!!\n"); |
684 | + errlogPrintf ("Unable to locate executable \"%s\".\n", pBaseExecutableName); |
685 | + errlogPrintf ("You may need to modify your \"path\"venvironment variable.\n"); |
686 | + } |
687 | return osiSpawnDetachedProcessFail; |
688 | - } |
689 | + } |
690 | |
691 | return osiSpawnDetachedProcessSuccess; |
692 | - |
693 | - /* |
694 | - use of spawn here causes problems when the ca repeater |
695 | - inherits open files (and sockets) from the spawning |
696 | - process |
697 | - |
698 | - status = _spawnlp (_P_DETACH, pBaseExecutableName, pBaseExecutableName, NULL); |
699 | - if (status<0) { |
700 | - errlogPrintf ("!!WARNING!!\n"); |
701 | - errlogPrintf ("Unable to locate the EPICS executable \"%s\".\n", |
702 | - pBaseExecutableName); |
703 | - errlogPrintf ("You may need to modify your environment.\n"); |
704 | - } |
705 | - */ |
706 | } |
707 | |
708 | === modified file 'src/libCom/osi/os/WIN32/osdTime.cpp' |
709 | --- src/libCom/osi/os/WIN32/osdTime.cpp 2012-07-20 23:11:15 +0000 |
710 | +++ src/libCom/osi/os/WIN32/osdTime.cpp 2014-08-19 03:55:55 +0000 |
711 | @@ -17,10 +17,10 @@ |
712 | // |
713 | // ANSI C |
714 | // |
715 | -#include <math.h> |
716 | -#include <time.h> |
717 | -#include <limits.h> |
718 | -#include <stdio.h> |
719 | +#include <cmath> |
720 | +#include <ctime> |
721 | +#include <climits> |
722 | +#include <cstdio> |
723 | |
724 | // |
725 | // WIN32 |
726 | @@ -28,6 +28,7 @@ |
727 | #define VC_EXTRALEAN |
728 | #define STRICT |
729 | #include <windows.h> |
730 | +#include <process.h> |
731 | |
732 | // |
733 | // EPICS |
734 | @@ -46,19 +47,26 @@ |
735 | # define debugPrintf(argsInParen) |
736 | #endif |
737 | |
738 | +extern "C" void setThreadName ( DWORD dwThreadID, LPCSTR szThreadName ); |
739 | + |
740 | static int osdTimeGetCurrent ( epicsTimeStamp *pDest ); |
741 | |
742 | // for mingw |
743 | #if !defined ( MAXLONGLONG ) |
744 | -#define MAXLONGLONG 0x7fffffffffffffffLL |
745 | +# define MAXLONGLONG 0x7fffffffffffffffLL |
746 | #endif |
747 | #if !defined ( MINLONGLONG ) |
748 | -#define MINLONGLONG (~0x7fffffffffffffffLL) |
749 | +# define MINLONGLONG ~0x7fffffffffffffffLL |
750 | +#endif |
751 | +#ifndef STACK_SIZE_PARAM_IS_A_RESERVATION |
752 | +# define STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000 |
753 | #endif |
754 | |
755 | static const LONGLONG epicsEpochInFileTime = 0x01b41e2a18d64000LL; |
756 | |
757 | -class currentTime : public epicsTimerNotify { |
758 | +static unsigned __stdcall _pllThreadEntry ( void * pCurrentTimeIn ); |
759 | + |
760 | +class currentTime { |
761 | public: |
762 | currentTime (); |
763 | ~currentTime (); |
764 | @@ -72,20 +80,24 @@ |
765 | LONGLONG perfCounterFreqPLL; |
766 | LONGLONG lastPerfCounterPLL; |
767 | LONGLONG lastFileTimePLL; |
768 | - epicsTimerQueueActive * pTimerQueue; |
769 | - epicsTimer * pTimer; |
770 | + HANDLE threadHandle; |
771 | + unsigned threadId; |
772 | bool perfCtrPresent; |
773 | + bool threadShutdownCmd; |
774 | + bool threadHasExited; |
775 | + void updatePLL (); |
776 | static const int pllDelay; /* integer seconds */ |
777 | - epicsTimerNotify::expireStatus expire ( const epicsTime & ); |
778 | + // cant be static because of diff btw __stdcall and __cdecl |
779 | + friend unsigned __stdcall _pllThreadEntry ( void * pCurrentTimeIn ); |
780 | }; |
781 | |
782 | +const int currentTime :: pllDelay = 5; |
783 | + |
784 | static currentTime * pCurrentTime = 0; |
785 | static const LONGLONG FILE_TIME_TICKS_PER_SEC = 10000000; |
786 | static const LONGLONG EPICS_TIME_TICKS_PER_SEC = 1000000000; |
787 | static const LONGLONG ET_TICKS_PER_FT_TICK = |
788 | EPICS_TIME_TICKS_PER_SEC / FILE_TIME_TICKS_PER_SEC; |
789 | - |
790 | -const int currentTime :: pllDelay = 5; |
791 | |
792 | // |
793 | // Start and register time provider |
794 | @@ -185,8 +197,8 @@ |
795 | } |
796 | |
797 | // |
798 | - // There are remarkable weaknessess in the FileTimeToLocalFileTime |
799 | - // interface so we dont use it here. Unfortunately, there is no |
800 | + // There are remarkable weaknesses in the FileTimeToLocalFileTime |
801 | + // interface so we don't use it here. Unfortunately, there is no |
802 | // corresponding function that works on file time. |
803 | // |
804 | SYSTEMTIME st; |
805 | @@ -263,9 +275,11 @@ |
806 | perfCounterFreqPLL ( 0 ), |
807 | lastPerfCounterPLL ( 0 ), |
808 | lastFileTimePLL ( 0 ), |
809 | - pTimerQueue ( 0 ), |
810 | - pTimer ( 0 ), |
811 | - perfCtrPresent ( false ) |
812 | + threadHandle ( 0 ), |
813 | + threadId ( 0 ), |
814 | + perfCtrPresent ( false ), |
815 | + threadShutdownCmd ( false ), |
816 | + threadHasExited ( false ) |
817 | { |
818 | InitializeCriticalSection ( & this->mutex ); |
819 | |
820 | @@ -308,15 +322,34 @@ |
821 | this->lastFileTimePLL = liFileTime.QuadPart; |
822 | } |
823 | |
824 | +void currentTime :: startPLL () |
825 | +{ |
826 | + // create frequency estimation thread when needed |
827 | + if ( this->perfCtrPresent && ! this->threadHandle ) { |
828 | + this->threadHandle = (HANDLE) |
829 | + _beginthreadex ( 0, 4096, _pllThreadEntry, this, |
830 | + CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION, |
831 | + & this->threadId ); |
832 | + assert ( this->threadHandle ); |
833 | + BOOL bstat = SetThreadPriority ( |
834 | + this->threadHandle, THREAD_PRIORITY_HIGHEST ); |
835 | + assert ( bstat ); |
836 | + DWORD wstat = ResumeThread ( this->threadHandle ); |
837 | + assert ( wstat != 0xFFFFFFFF ); |
838 | + } |
839 | +} |
840 | + |
841 | currentTime::~currentTime () |
842 | { |
843 | + EnterCriticalSection ( & this->mutex ); |
844 | + this->threadShutdownCmd = true; |
845 | + while ( ! this->threadHasExited ) { |
846 | + LeaveCriticalSection ( & this->mutex ); |
847 | + Sleep ( 250 /* mS */ ); |
848 | + EnterCriticalSection ( & this->mutex ); |
849 | + } |
850 | + LeaveCriticalSection ( & this->mutex ); |
851 | DeleteCriticalSection ( & this->mutex ); |
852 | - if ( this->pTimer ) { |
853 | - this->pTimer->destroy (); |
854 | - } |
855 | - if ( this->pTimerQueue ) { |
856 | - this->pTimerQueue->release (); |
857 | - } |
858 | } |
859 | |
860 | void currentTime::getCurrentTime ( epicsTimeStamp & dest ) |
861 | @@ -386,7 +419,7 @@ |
862 | // Maintain corrected version of the performance counter's frequency using |
863 | // a phase locked loop. This approach is similar to NTP's. |
864 | // |
865 | -epicsTimerNotify::expireStatus currentTime::expire ( const epicsTime & ) |
866 | +void currentTime :: updatePLL () |
867 | { |
868 | EnterCriticalSection ( & this->mutex ); |
869 | |
870 | @@ -431,7 +464,7 @@ |
871 | if ( fileTimeDiff <= 0 ) { |
872 | LeaveCriticalSection( & this->mutex ); |
873 | debugPrintf ( ( "currentTime: file time difference in PLL was less than zero\n" ) ); |
874 | - return expireStatus ( restart, pllDelay /* sec */ ); |
875 | + return; |
876 | } |
877 | |
878 | LONGLONG freq = ( FILE_TIME_TICKS_PER_SEC * perfCounterDiff ) / fileTimeDiff; |
879 | @@ -445,7 +478,7 @@ |
880 | static_cast < int > ( -bound ), |
881 | static_cast < int > ( delta ), |
882 | static_cast < int > ( bound ) ) ); |
883 | - return expireStatus ( restart, pllDelay /* sec */ ); |
884 | + return; |
885 | } |
886 | |
887 | // update feedback loop estimating the performance counter's frequency |
888 | @@ -482,7 +515,7 @@ |
889 | debugPrintf ( ( "perf ctr measured delay out of bounds m=%d max=%d\n", |
890 | static_cast < int > ( perfCounterDiffSinceLastFetch ), |
891 | static_cast < int > ( expectedDly + bnd ) ) ); |
892 | - return expireStatus ( restart, pllDelay /* sec */ ); |
893 | + return; |
894 | } |
895 | } |
896 | |
897 | @@ -521,9 +554,9 @@ |
898 | |
899 | delta = epicsTimeFromCurrentFileTime - this->epicsTimeLast; |
900 | if ( delta > EPICS_TIME_TICKS_PER_SEC || delta < -EPICS_TIME_TICKS_PER_SEC ) { |
901 | - // When there is an abrupt shift in the current computed time vs |
902 | - // the time derived from the current file time then someone has |
903 | - // probabably adjusted the real time clock and the best reaction |
904 | + // When there is an abrupt shift in the current computed time vs |
905 | + // the time derived from the current file time then someone has |
906 | + // probably adjusted the real time clock and the best reaction |
907 | // is to just assume the new time base |
908 | this->epicsTimeLast = epicsTimeFromCurrentFileTime; |
909 | this->perfCounterFreq = this->perfCounterFreqPLL; |
910 | @@ -563,24 +596,31 @@ |
911 | ( this->perfCounterFreqPLL - sysFreq.QuadPart ); |
912 | freqEstDiff /= sysFreq.QuadPart; |
913 | freqEstDiff *= 100.0; |
914 | - debugPrintf ( ( "currentTime: freq delta %f %% freq est delta %f %% time delta %f sec\n", |
915 | - freqDiff, freqEstDiff, static_cast < double > ( delta ) / EPICS_TIME_TICKS_PER_SEC ) ); |
916 | + debugPrintf ( ( "currentTime: freq delta %f %% freq est " |
917 | + "delta %f %% time delta %f sec\n", |
918 | + freqDiff, |
919 | + freqEstDiff, |
920 | + static_cast < double > ( delta ) / |
921 | + EPICS_TIME_TICKS_PER_SEC ) ); |
922 | # endif |
923 | } |
924 | |
925 | LeaveCriticalSection ( & this->mutex ); |
926 | - |
927 | - return expireStatus ( restart, pllDelay /* sec */ ); |
928 | } |
929 | |
930 | -void currentTime::startPLL () |
931 | +static unsigned __stdcall _pllThreadEntry ( void * pCurrentTimeIn ) |
932 | { |
933 | - // create frequency estimation timer when needed |
934 | - if ( this->perfCtrPresent && ! this->pTimerQueue ) { |
935 | - this->pTimerQueue = & epicsTimerQueueActive::allocate ( true ); |
936 | - this->pTimer = & this->pTimerQueue->createTimer (); |
937 | - this->pTimer->start ( *this, pllDelay ); |
938 | + currentTime * pCT = |
939 | + reinterpret_cast < currentTime * > ( pCurrentTimeIn ); |
940 | + setThreadName ( pCT->threadId, "EPICS Time PLL" ); |
941 | + while ( ! pCT->threadShutdownCmd ) { |
942 | + Sleep ( currentTime :: pllDelay * 1000 /* mS */ ); |
943 | + pCT->updatePLL (); |
944 | } |
945 | + EnterCriticalSection ( & pCT->mutex ); |
946 | + pCT->threadHasExited = true; |
947 | + LeaveCriticalSection ( & pCT->mutex ); |
948 | + return 1; |
949 | } |
950 | |
951 | epicsTime::operator FILETIME () const |
952 | |
953 | === modified file 'src/libCom/osi/os/vxWorks/osdSock.c' |
954 | --- src/libCom/osi/os/vxWorks/osdSock.c 2013-06-07 23:08:38 +0000 |
955 | +++ src/libCom/osi/os/vxWorks/osdSock.c 2014-08-19 03:55:55 +0000 |
956 | @@ -115,18 +115,11 @@ |
957 | epicsShareFunc int epicsShareAPI |
958 | hostToIPAddr(const char *pHostName, struct in_addr *pIPA) |
959 | { |
960 | - int addr; |
961 | - |
962 | - addr = hostGetByName((char *)pHostName); |
963 | - if (addr != ERROR) { |
964 | - pIPA->s_addr = (unsigned long) addr; |
965 | - } |
966 | - else if (inet_aton((char *)pHostName, pIPA) == ERROR) { |
967 | - /* |
968 | - * return indicating an error |
969 | - */ |
970 | + int addr = hostGetByName ( (char *) pHostName ); |
971 | + if ( addr == ERROR ) { |
972 | return -1; |
973 | } |
974 | + pIPA->s_addr = (unsigned long) addr; |
975 | |
976 | /* |
977 | * success |
978 | |
979 | === modified file 'src/libCom/osi/osiNTPTime.c' |
980 | --- src/libCom/osi/osiNTPTime.c 2014-02-13 16:09:12 +0000 |
981 | +++ src/libCom/osi/osiNTPTime.c 2014-08-19 03:55:55 +0000 |
982 | @@ -18,6 +18,7 @@ |
983 | #include <time.h> |
984 | #include <errno.h> |
985 | |
986 | +#define epicsExportSharedSymbols |
987 | #include "epicsEvent.h" |
988 | #include "epicsExit.h" |
989 | #include "epicsTypes.h" |
990 | |
991 | === modified file 'src/libCom/test/blockingSockTest.cpp' |
992 | --- src/libCom/test/blockingSockTest.cpp 2014-03-13 20:04:31 +0000 |
993 | +++ src/libCom/test/blockingSockTest.cpp 2014-08-19 03:55:55 +0000 |
994 | @@ -56,11 +56,16 @@ |
995 | |
996 | class server { |
997 | public: |
998 | - server ( address & ); |
999 | + server ( const address & ); |
1000 | void start (); |
1001 | void daemon (); |
1002 | +<<<<<<< TREE |
1003 | void stop (); |
1004 | +======= |
1005 | + address addr () const; |
1006 | +>>>>>>> MERGE-SOURCE |
1007 | protected: |
1008 | + address srvaddr; |
1009 | SOCKET sock; |
1010 | epicsThreadId id; |
1011 | bool exit; |
1012 | @@ -155,20 +160,20 @@ |
1013 | pSrv->daemon (); |
1014 | } |
1015 | |
1016 | -server::server ( address & addrIn ) : |
1017 | +server::server ( const address & addrIn ) : |
1018 | + srvaddr ( addrIn ), |
1019 | sock ( epicsSocketCreate ( AF_INET, SOCK_STREAM, IPPROTO_TCP ) ), |
1020 | id ( 0 ), exit ( false ) |
1021 | { |
1022 | testOk ( this->sock != INVALID_SOCKET, "Server socket valid" ); |
1023 | |
1024 | // setup server side |
1025 | - int status = bind ( this->sock, |
1026 | - & addrIn.sa, sizeof ( addrIn ) ); |
1027 | + osiSocklen_t slen = sizeof ( this->srvaddr ); |
1028 | + int status = bind ( this->sock, & this->srvaddr.sa, slen ); |
1029 | if ( status ) { |
1030 | testDiag ( "bind to server socket failed, status = %d", status ); |
1031 | } |
1032 | - osiSocklen_t slen = sizeof ( addrIn ); |
1033 | - if ( getsockname(this->sock, &addrIn.sa, &slen) != 0 ) { |
1034 | + if ( getsockname(this->sock, & this->srvaddr.sa, & slen) != 0 ) { |
1035 | testAbort ( "Failed to read socket address" ); |
1036 | } |
1037 | status = listen ( this->sock, 10 ); |
1038 | @@ -184,7 +189,7 @@ |
1039 | testOk ( this->id != 0, "Server thread created" ); |
1040 | } |
1041 | |
1042 | -void server::daemon () |
1043 | +void server::daemon () |
1044 | { |
1045 | while ( ! this->exit ) { |
1046 | // accept client side |
1047 | @@ -200,19 +205,27 @@ |
1048 | } |
1049 | } |
1050 | |
1051 | +<<<<<<< TREE |
1052 | void server::stop () |
1053 | { |
1054 | this->exit = true; |
1055 | epicsSocketDestroy ( this->sock ); |
1056 | } |
1057 | |
1058 | +======= |
1059 | +address server::addr () const |
1060 | +{ |
1061 | + return this->srvaddr; |
1062 | +} |
1063 | + |
1064 | +>>>>>>> MERGE-SOURCE |
1065 | serverCircuit::serverCircuit ( SOCKET sockIn ) : |
1066 | circuit ( sockIn ) |
1067 | { |
1068 | circuit * pCir = this; |
1069 | - epicsThreadId threadId = epicsThreadCreate ( |
1070 | - "server circuit", epicsThreadPriorityMedium, |
1071 | - epicsThreadGetStackSize(epicsThreadStackMedium), |
1072 | + epicsThreadId threadId = epicsThreadCreate ( |
1073 | + "server circuit", epicsThreadPriorityMedium, |
1074 | + epicsThreadGetStackSize(epicsThreadStackMedium), |
1075 | socketRecvTest, pCir ); |
1076 | testOk ( threadId != 0, "Server circuit thread created" ); |
1077 | } |
1078 | @@ -233,7 +246,7 @@ |
1079 | {esscimqi_socketBothShutdownRequired, "esscimqi_socketBothShutdownRequired" }, |
1080 | {esscimqi_socketSigAlarmRequired, "esscimqi_socketSigAlarmRequired" } |
1081 | }; |
1082 | - |
1083 | + |
1084 | for (unsigned i=0; i < (sizeof(mechs) / sizeof(mechs[0])); ++i) { |
1085 | if (mech == mechs[i].mech) |
1086 | return mechs[i].name; |
1087 | @@ -254,6 +267,7 @@ |
1088 | |
1089 | server srv ( addr ); |
1090 | srv.start (); |
1091 | + addr = srv.addr (); |
1092 | clientCircuit client ( addr ); |
1093 | |
1094 | epicsThreadSleep ( 1.0 ); |
1095 | |
1096 | === modified file 'src/libCom/test/epicsTimeTest.cpp' |
1097 | --- src/libCom/test/epicsTimeTest.cpp 2014-01-29 22:52:22 +0000 |
1098 | +++ src/libCom/test/epicsTimeTest.cpp 2014-08-19 03:55:55 +0000 |
1099 | @@ -9,11 +9,6 @@ |
1100 | /* |
1101 | * Authors: Jeff Hill, Marty Kraimer and Andrew Johnson |
1102 | */ |
1103 | - |
1104 | -#ifdef __SUNPRO_CC |
1105 | -using namespace std; |
1106 | -#endif |
1107 | - |
1108 | #include <cstddef> |
1109 | #include <cstdio> |
1110 | #include <ctime> |
After committing a few changes to this branch the only parts I don't currently like are modifications to epicsThread.h and epicsTime.h which include a C standard header in a C build or the equivalent C++ header in a C++ build. The epicsThread.h file also adds a using declaration for std::size_t in C++, which does not seem like a good idea to me. We have other include files that pull in C standard headers in C++ builds, and I would like to see what other people think before accepting these kinds of changes.