0

I need to get a timestamp in resolution of microseconds. I found options like using timeval struct and calling gettimeofday. The problem is all structs have long variables in them and I can work only with 32 bit variables.

How can I get a timestamp (in c) using only 32 bit variables?

user2958571
  • 133
  • 1
  • 6
  • 13
  • If the platform you're working on provides 64-bit `long` values for the `suseconds_t` type, why can't you use that? If the value is 64 bits, your platform obviously supports 64-bit values natively. – Andrew Henle Jul 09 '19 at 11:59
  • Look at the first of the two options in the accepted answer _[here](https://stackoverflow.com/questions/11765301/how-do-i-get-the-unix-timestamp-in-c-as-an-int)_ – ryyker Jul 09 '19 at 12:01
  • 2
    Note: using 32-bit variables to store a micro-second time stamp can encompass a time span of a little over one hour. – Weather Vane Jul 09 '19 at 12:13
  • The run time is not long (up to 30 minutes). – user2958571 Jul 09 '19 at 12:40
  • Possible duplicate of [how to get timestamp in c](https://stackoverflow.com/questions/15436060/how-to-get-timestamp-in-c) – SimonC Jul 09 '19 at 13:37
  • *The run time is not long (up to 30 minutes)* And how do you plan on handling overflow? A 30-minute runtime for something that can only count for an hour has a 50% chance of overflow. Has the source of the 32-bit requirement even thought of that? – Andrew Henle Jul 09 '19 at 14:26

2 Answers2

1

This site is a very good reference for time and clock related programming in general, including function prototypes, struct definitions as well as programming examples that are relevant to your request. You should have a look.

There are several answers from here that may be adaptable to what you need. The accepted answer is generic:

For 32-bit systems:

fprintf(stdout, "%u\n", (unsigned)time(NULL)); )_

This answer for the same question, specifically addresses uS resolution. However it is POSIX specific, and may violate your specifications. :

#include <stdio.h>
#include <time.h>
#include <stdint.h>
#include <inttypes.h>
int main(void) {

    struct timespec tms;

    /* The C11 way */
    /* if (! timespec_get(&tms, TIME_UTC)) { */

    /* POSIX.1-2008 way */
    if (clock_gettime(CLOCK_REALTIME,&tms)) {
        return -1;
    }
    /* seconds, multiplied with 1 million */
    int64_t micros = tms.tv_sec * 1000000;
    /* Add full microseconds */
    micros += tms.tv_nsec/1000;
    /* round up if necessary */
    if (tms.tv_nsec % 1000 >= 500) {
        ++micros;
    }
    printf("Microseconds: %"PRId64"\n",micros);
    return 0;
}
ryyker
  • 22,849
  • 3
  • 43
  • 87
  • 1
    `time()` returns seconds, not microseconds, and `clock_gettime()` uses 64 bits if `long` is 64 bits, so neither fully fits the stated requirements. IMO it's that 32-bit requirement that is nonsensical and pretty much makes the question unanswerable. – Andrew Henle Jul 09 '19 at 12:14
  • this is the requirement that I received. I don't need it to run for a long time so it should be enough. – user2958571 Jul 09 '19 at 12:39
  • @AndrewHenle - Agreed, thanks for pointing out both observations. I made some small edits, not adjusting the examples, but simply pointing out their deficiencies. – ryyker Jul 09 '19 at 14:19
0

If the struct timeval fields are in long integer format (which can be or cannot) in 32bit format, is because you need it to be that size. Let's do some analysis: I took this timestamp in NTP format, and converted it to struct timeval format (for a now timestamp) on my system:

ntpts.c:120:process:  NTP(dec): 3771731346.612550000
ntpts.c:121:process:  NTP(hex): 0xe0d00d92.9cd013a9
ntpts.c:123:process:      UNIX: 1562742546/0x5d258f12
ntpts.c:135:process:    gmtime: 10/jul/2019, 07:09:06.612550000
ntpts.c:136:process: localtime: 10/jul/2019, 10:09:06.612550000

tv_sec  ==> 1562742546
tv_usec ==>     612550

so to get a single timestamp with that resolution (number of seconds since 00:00h jan/1/1970, and microseconds) you need at least 52 bits (well, normally tv_sec is a long or long long 64bit field, because of the overflow that will happen in feb, 2038, and some systems have already patched this) and the tv_usec could be fit in a 24bit variable (usec go from 0 to 999999, so they need at least 20bit), but compiler padding would make it 32bit size anyway, at a minimum.

In case you want to conserve full usec resolution with 32bit, you'll need at least 20 bits to represent the fraction of a second and you'll have only 12 bit to represent the integer part. In that case, you'll be able to express only seconds from 0 to 4095, which is some more than one hour (01h8m16s). This is possible to handle, but to make that timestamp absolute, you'll need to reference which absolute hour in history this timestamp belongs to.

On the other side, if you reduce your granularity to msec, you can get more than 1000 hours of reference window, you need to consider this to finally decide what to do next.

AMENDMENT

By the way, the gettimeofday(2) system call is actually deprecated. Nearly all systems in use today use the clock_gettime(2) system call, which has nanosecond resolution, and allows you to select the proper system clock to get the timestamp.

Community
  • 1
  • 1
Luis Colorado
  • 10,974
  • 1
  • 16
  • 31