Given it’s eight bytes I wondered if something like this would work:
GetTickCount64 procedure,real,pascal,name('GetTickCount64')
myResult real
myUINT64 group,over(myResult)
lo ulong
hi ulong
end
myResult = sdkGetTickCount64()
I would get rid of the Over Real. You must prototype to return a Real so the compiler knows it’s getting an 8 byte return value, but it is not a Real internally.
GetTickCount64 procedure,REAL,pascal,name('GetTickCount64'),DLL(1l
myResult group !no-h> ,over(myResult)
lo ulong
hi ulong
end
myResult = sdkGetTickCount64()
If you are going to compare to the 32 bit GetTickCount() you must read MSDN that it rolls over at 49.7 days. As long as your system has been up less than that the myResult.LO should be close and .HI = Zero
Mike. Unless I’m losing my mind I think you have deleted an earlier response in favour of this “use a real” approach?
I didn’t keep a copy of that earlier response but was acting on it and things seemed good. It was along these lines:
ticks64 group
hi long
lo ulong
end
ticks64.lo = GetTickCount64() ! with the api call declared as returning a long
It did seem too magical - I’m thinking you found that ticks64.hi was never populated?
Background is that I’ve used GetTickCount to monitor server runtimes for ever and it’s annoying when they start going back in time after 21 days or so. I now realise that using ulongs would probably have pushed that out to 43 days but wanted to finally tidy it up.
Using that “ticks64 group” approach, one particular server is now moving forward again (27 days+) - nice but only because ulongs got involved? Milliseconds-wise it’s nearly 3 weeks away from exceeding a 32 bit number.
I did try your “assign to a real” approach but got a negative number in line with GetTickCount().
Really appreciate your input. For me, this is a very low priority, would be nice to understand and resolve thing…
Was hoping for a simple clarion way/trick. But now suspect that was naive - my current picture is that when clarion deals with api “functions” (c/pascal) it’s always expecting a 32-bit number back. Which might well be a pointer to something else but that’s all it permits - (LONG/ULONG, your choice) numbers. Given that, fact that you can prototype real / string / cstring return values doesn’t make much sense on a Sunday afternoon. So my picture is probably still wrong.
Appreciate everyone’s input. And if Mike D can’t make it work then probably case closed.
PROGRAM
PRAGMA('compile(MyGetTickCount64.a)')
MAP
MODULE('MyGetTickCount64.a')
GetTickCount64(*LONG pTicksLo, *LONG pTicksHi),PASCAL,NAME('__ASM__GetTickCount64')
END
END
ticks64_lo LONG, AUTO
ticks64_hi LONG, AUTO
CODE
GetTickCount64(ticks64_lo, ticks64_hi)
MyGetTickCount64.a:
module gettickcount64
(* c++ call in assembler: *)
(* ULONGLONG ticks = GetTickCount64(); *)
(* 003E2466 mov esi,esp *)
(* 003E2468 call dword ptr [__imp__GetTickCount64@0 (03ED000h)] *)
(* 003E246E cmp esi,esp *)
(* 003E2470 call __RTC_CheckEsp (03E1294h) *)
(* 003E2475 mov dword ptr [ticks],eax *)
(* 003E2478 mov dword ptr [ebp-8],edx *)
segment GETTICKCOUNT64_TEXT("CODE",00029H)
extrn GetTickCount64
public __ASM__GetTickCount64:
push ebp (* save stack frame *)
mov ebp, esp (* set local ebp *)
push ebx (* just in case preserve ebx *)
call GetTickCount64 (* call api *)
mov ebx, [esp][12] (* copy Lo address to ebx *)
mov [ebx], eax (* copy Lo value from eax *)
mov ebx, [esp][16] (* copy Hi address to ebx *)
mov [ebx], edx (* copy Hi value from edx *)
pop ebx (* restore ebx *)
pop ebp (* restore stack frame *)
ret 8 (* pop 2 pushed arguments *)
end
Late in the day here but I understand how to incorporate asm and already have some on board in my apps so should be easy enough. Will try to take a look tomorrow and revert here. But there’s no rush - the one long-running machine that triggered me is at 39 days so I’ve got 10 days to get this in place (and hope it doesn’t get restarted in the interim).
Whole thing was always a bit academic for me - just nice to see runtime reliably reported into hundreds of days. But perhaps you benefit elsewhere.
Interesting but I think Mr Chen is being a bit picky there. If you are monitoring machines and want an idea of how long they’ve been running then the GetTickCount route seems best option.
In my case it shows anything but not running time - yesterday it was 10 days, right now it is 10 hours, if it would be the time from system start, then both values are completely wrong.