I have a packet sniffer (see below). To measure bandwidth I think I need to start a timer at the beginning of receving data. Record the number of bytes that has been transmitted and then calculate the average bandwidth. To measure time time to receive/send data I did:
int main() {
//usual packet sniffer staff up untill while loop
struct pcap_pkthdr header;
const unsigned char *packet;
char errbuf[PCAP_ERRBUF_SIZE];
char *device;
pcap_t *pcap_handle;
int i;
device = pcap_lookupdev(errbuf);
if (device == NULL) perror("pcap_lookupdev failed");
printf("Sniffing on device %s\n", device);
pcap_handle = pcap_open_live(device, 4096, 1, 0, errbuf);
if (pcap_handle == NULL) perror("pcap_open_live failed");
while (1) {
//starting the timer
double diff = 0.0;
time_t start;
time_t stop;
char buff[128];
time(&start);
//receiving packet
packet = pcap_next(pcap_handle, &header);
//stopping the timer
time(&stop);
//measuring time of receiving data
diff = difftime(stop, start);
process_packet(packet, header.len, diff);
}
}
diff turns out to always be 0.0000, which is probably wrong. Is my understanding correct, if yes, Is there any problems with code?
I also tries using milliseconds:
float diff;
clock_t start;
clock_t stop;
char buff[128];
start = clock();
packet = pcap_next(pcap_handle, &header);//just creates a pointer in no time
stop = clock();
diff = (((float)stop - (float)start) / 1000000.0F ) * 1000;
The same output...
Insufficient number of samples or too coarse a clock.
The number of packets between the start and stop are likely far too small. time_t typically only has a resolution of 1 second. clock_t has an implementation defined number of ticks per seconds of CLOCKS_PER_SEC. I've seen values of 18.2 or 100 or 1000 and others. It too, may be insufficient for 1 data packet.
Recommend increase the time of bytes transferred to be at least 10x the clock period. So if you are using time_t and running at 19,200 baud, then transfer 192,000 bytes.
For consistency, synchronizing the start time helps. Sample below works for clock_t, just scale accordingly.
// sync
time_t was;
time(&was);
time_t now;
do {
time(&now);
} while (now == was);
// do test
do_test(); // about 10 seconds;
// results
time_t later;
time(&later);
time_t delta = late - now;
BitsPerDataByte = 1+8+1;
double TestedBaud = 1.0*DataBytesSent*BitsPerDataByte/delta;
Related
I have a function and I want the function to stop running once it has been running for a certain number of milliseconds. This function works for seconds but I want to test it for milliseconds. How do I do this? If I set eliminate = 1, it corresponds to 1 second. How do I set eliminate = 5 ms?
Function:
void clsfy_proc(S_SNR_TARGET_SET pSonarTargetSet, unsigned char *target_num, time_t eliminate)
{
// get timing
time_t _start = time(NULL);
time_t _end = _start + eliminate;
int _eliminate = 0;
//some code
time_t start = time(NULL);
time_t end = start + eliminate;
for(_tidx = 0; _tidx < pSonarTargetSet[_i].num; _tidx++) {
// check timing
time_t _current = time(NULL);
if (_current > _end) {
printf("clsfy_proc(1), Eliminate due to timeout\n");
_eliminate = 1;
break;
}
//some code
if (_eliminate == 1)
break;
}
//some code
}
time_t is an absolute time, represented as the integer number of seconds since the UNIX epoch (midnight GMT, 1 January 1970). It is useful as an unambiguous, easy-to-work-with representation of a point in time.
clock_t is a relative measurement of time, represented by an integer number of clock ticks since some point in time (possibly the computer's bootup, but no guarantees, as it may roll over quite often). There are CLOCKS_PER_SEC clock ticks per second; the value of this constant can vary between different operating systems. It is sometimes used for timing purposes, but it is not very good at it due to its relatively low resolution.
One small example for clock_t:
#include <time.h>
#include <stdio.h>
int main () {
clock_t start_t, end_t, total_t;
int i;
start_t = clock();
printf("Starting of the program, start_t = %ld\n", start_t);
for(i=0; i< 10000000; i++) { }
end_t = clock();
printf("End of the big loop, end_t = %ld\n", end_t);
total_t = (double)(end_t - start_t) / CLOCKS_PER_SEC;
printf("Total time taken by CPU: %f\n", total_t );
return(0);
}
You can use getrusage().
Please see the example:
Source: http://www.cs.tufts.edu/comp/111/examples/Time/getrusage.c
#include <stdio.h>
#include <sys/time.h>
#include <sys/resource.h>
///////////////////////////////////
// measure user and system time using the "getrusage" call.
///////////////////////////////////
//struct rusage {
// struct timeval ru_utime; /* user CPU time used */
// struct timeval ru_stime; /* system CPU time used */
// long ru_maxrss; /* maximum resident set size */
// long ru_ixrss; /* integral shared memory size */
// long ru_idrss; /* integral unshared data size */
// long ru_isrss; /* integral unshared stack size */
// long ru_minflt; /* page reclaims (soft page faults) */
// long ru_majflt; /* page faults (hard page faults) */
// long ru_nswap; /* swaps */
// long ru_inblock; /* block input operations */
// long ru_oublock; /* block output operations */
// long ru_msgsnd; /* IPC messages sent */
// long ru_msgrcv; /* IPC messages received */
// long ru_nsignals; /* signals received */
// long ru_nvcsw; /* voluntary context switches */
// long ru_nivcsw; /* involuntary context switches */
//};
//struct timeval
// {
// long int tv_sec; /* Seconds. */
// long int tv_usec; /* Microseconds. */
// };
main () {
struct rusage buf;
// chew up some CPU time
int i,j; for (i=0,j=0; i<100000000; i++) { j+=i*i; }
getrusage(RUSAGE_SELF, &buf);
printf("user seconds without microseconds: %ld\n", buf.ru_utime.tv_sec);
printf("user microseconds: %ld\n", buf.ru_utime.tv_usec);
printf("total user seconds: %e\n",
(double) buf.ru_utime.tv_sec
+ (double) buf.ru_utime.tv_usec / (double) 1000000);
}
When I output the microseconds field for gettimeofday(), I notice that the microsecond field is larger than 1,000,000. Does anyone know why this is? And does this imply that I've been interpreting gettimeofday() wrong?
For the record, my assumption is that the current time (in microseconds) according to gettimeofday() is the following:
struct timeval ts;
gettimeofday(&ts, NULL);
printf("%zu", ts.tv_sec * 1000000 + ts.tv_usec);
Edit: Here is the code that is causing the problem. After the comments below, the printf() might be at fault.
struct timeval curr_time;
gettimeofday(&curr_time, NULL);
printf("Done-arino! Onto the matrix multiplication (at %zu s, %03zu ms)\n", curr_time.tv_sec, curr_time.tv_usec);
// Matrix Multiplication
struct timeval start_tv, end_tv, elapsed_tv;
gettimeofday(&start_tv, NULL);
for (i = 0; i < N; i++)
for (j = 0; j < N; j++)
for (k = 0; k < N; k++)
C[i][j] += A[i][k] * B[k][j];
gettimeofday(&end_tv, NULL);
timersub(&end_tv, &start_tv, &elapsed_tv);
// Print results
printf("Elapsed time: %zu s, %03zu ms\n", elapsed_tv.tv_sec, elapsed_tv.tv_usec / 1000);
After a successful to gettimeofday, yes, tv_usec is guaranteed to be strictly less than 1000000.
If you (think you) saw a value of 1000000 or greater, then yes, it's likely you were doing something wrong.
A frequent mistake is to add or subtract two struct timeval values naively, without implementing proper carry or borrow between the tv_sec and tv_usec fields, and this can easily lead to (mistaken and wrong) values in tv_usec greater than 1000000. (In your edited post you mention subtracting timespecs, but you're using the system-supplied timersub function which ought to get the borrow right.)
If you were using a struct timespec instead of struct timeval, and if a leap second were going on, and if you were (miraculously) using an OS kernel that implemented the CLOCK_UTC clock type proposed by Markus Kuhn at https://www.cl.cam.ac.uk/~mgk25/posix-clocks.html, you'd see tv_nsec values greater than 1000000000, but that's a lot of "if"s. (And to my knowledge no kernel in widespread use has ever implemented CLOCK_UTC.)
You'll need to show some more convincing code, and identify the platform on which you run into the problem.
For example:
#include <stdio.h>
#include <sys/time.h>
int main(void)
{
while (1)
{
struct timeval ts;
if (gettimeofday(&ts, 0) == 0 && ts.tv_usec >= 1000000)
printf("%lu s; %lu µs\n", (long)ts.tv_sec, (long)ts.tv_usec);
}
return 0;
}
The very busy loop is a tad irksome; maybe you should use nanosleep() to sleep for a microsecond or two on every iteration:
#include <stdio.h>
#include <sys/time.h>
#include <time.h>
int main(void)
{
while (1)
{
struct timeval tv;
if (gettimeofday(&tv, 0) == 0 && tv.tv_usec >= 1000000)
printf("%lu s; %lu µs\n", (long)tv.tv_sec, (long)tv.tv_usec);
struct timespec ts = { .tv_sec = 0, .tv_nsec = 2000 };
nanosleep(&ts, 0);
}
return 0;
}
Or, including a progress meter to demonstrate that the code is running:
#include <stdio.h>
#include <sys/time.h>
#include <time.h>
int main(void)
{
size_t loop_count = 0;
size_t line_count = 0;
while (1)
{
struct timeval tv;
if (gettimeofday(&tv, 0) == 0 && tv.tv_usec >= 1000000)
printf("%lu s; %lu µs\n", (long)tv.tv_sec, (long)tv.tv_usec);
struct timespec ts = { .tv_sec = 0, .tv_nsec = 2000 };
nanosleep(&ts, 0);
if (++loop_count > 100000)
{
loop_count = 0;
putchar('.');
line_count++;
if (line_count >= 50)
{
putchar('\n');
line_count = 0;
}
fflush(stdout);
}
}
return 0;
}
timersub()
On an Ubuntu 16.04 LTS VM, I can find file /usr/include/x86_64-linux-gnu/sys/time.h containing a macro:
# define timersub(a, b, result) \
do { \
(result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
(result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
if ((result)->tv_usec < 0) { \
--(result)->tv_sec; \
(result)->tv_usec += 1000000; \
} \
} while (0)
All the indications I can see are that tv_usec is an __u32, an unsigned quantity. If that's the case, then the < 0 condition will never be true and you may sometimes see grotesquely large positive values instead. YMMV, of course.
Even my mileage varies
Further scrutiny shows that while there are headers that seem to use __u32 for tv_usec, those are not the main system headers.
/usr/include/linux/time.h: __kernel_suseconds_t tv_usec; /* microseconds */
/usr/include/linux/can/bcm.h: long tv_usec;
/usr/include/drm/exynos_drm.h: __u32 tv_usec;
/usr/include/drm/exynos_drm.h: __u32 tv_usec;
/usr/include/drm/vmwgfx_drm.h: uint32_t tv_usec;
/usr/include/drm/drm.h: __u32 tv_usec;
/usr/include/rpc/auth_des.h: uint32_t tv_usec; /* Microseconds. */
/usr/include/valgrind/vki/vki-darwin.h:#define vki_tv_usec tv_usec
/usr/include/valgrind/vki/vki-linux.h: vki_suseconds_t tv_usec; /* microseconds */
/usr/include/rpcsvc/rstat.x: unsigned int tv_usec; /* and microseconds */
/usr/include/rpcsvc/rstat.h: u_int tv_usec;
/usr/include/x86_64-linux-gnu/bits/utmpx.h: __int32_t tv_usec; /* Microseconds. */
/usr/include/x86_64-linux-gnu/bits/time.h: __suseconds_t tv_usec; /* Microseconds. */
/usr/include/x86_64-linux-gnu/bits/utmp.h: int32_t tv_usec; /* Microseconds. */
/usr/include/x86_64-linux-gnu/sys/time.h: (ts)->tv_nsec = (tv)->tv_usec * 1000; \
/usr/include/x86_64-linux-gnu/sys/time.h: (tv)->tv_usec = (ts)->tv_nsec / 1000; \
/usr/include/x86_64-linux-gnu/sys/time.h:# define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
/usr/include/x86_64-linux-gnu/sys/time.h:# define timerclear(tvp) ((tvp)->tv_sec = (tvp)->tv_usec = 0)
/usr/include/x86_64-linux-gnu/sys/time.h: ((a)->tv_usec CMP (b)->tv_usec) : \
/usr/include/x86_64-linux-gnu/sys/time.h: (result)->tv_usec = (a)->tv_usec + (b)->tv_usec; \
/usr/include/x86_64-linux-gnu/sys/time.h: if ((result)->tv_usec >= 1000000) \
/usr/include/x86_64-linux-gnu/sys/time.h: (result)->tv_usec -= 1000000; \
/usr/include/x86_64-linux-gnu/sys/time.h: (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
/usr/include/x86_64-linux-gnu/sys/time.h: if ((result)->tv_usec < 0) { \
/usr/include/x86_64-linux-gnu/sys/time.h: (result)->tv_usec += 1000000; \
It's worrying to see any code using an unsigned type for a member with that name, but that doesn't mean it is happening for code using struct timeval and timersub().
This code:
#include <sys/time.h>
#include <stdio.h>
int main(void)
{
struct timeval t = { .tv_sec = 0, .tv_usec = -1 };
printf("%ld %ld\n", (long)t.tv_sec, (long)t.tv_usec);
return 0;
}
compiled for 64-bit (so long is big enough to hold anything that tv_usec could be defined as) prints 0 -1 as it should. It would be possible to initialize the tv_usec member to 0, decrement it, and verify that it is negative, and various other related tests.
So, the problem isn't as simple as "timersub() is wrong" — which is an immense relief.
Your printf formats are suspect, and could be causing this problem.
The %zu format is for printing size_t values. But neither tv_sec nor tv_usec has type size_t.
On a modern system, size_t is likely to be 64 bits. But if either tv_sec or tv_usec is not, printf will end up printing those values quite wrongly.
I changed your printfs to
printf("Done-arino! Onto the matrix multiplication (at %ld s, %03u ms)\n",
curr_time.tv_sec, curr_time.tv_usec);
and
printf("Elapsed time: %ld s, %03u ms\n",
elapsed_tv.tv_sec, elapsed_tv.tv_usec / 1000);
These won't necessarily be correct for you, though — it depends on your system's specific choices for tv_sec and tv_usec.
The general and portable way to print a value of an implementation-defined type like this is to explicitly cast it to the largest type it can be, then use the printf format corresponding to the cast-to type. For example:
printf("Done-arino! Onto the matrix multiplication (at %ld s, %03ld ms)\n",
(long)curr_time.tv_sec, (long)curr_time.tv_usec);
printf("Elapsed time: %ld s, %03ld ms\n",
(long)elapsed_tv.tv_sec, (long)elapsed_tv.tv_usec / 1000);
The cast might or might not be a no-op, but the point is that, no matter what the original type was, you end up with something that matches what you've told printf to expect.
I need to wait for n bytes of data (count is known) on a serial port or socket on Linux.
Currently I use a loop with poll, measure the time and decrement the timeout:
static int int_read_poll(int fd, uint8_t *buffer, size_t count, int timeout)
{
struct pollfd pfd;
int rc;
pfd.fd = fd;
pfd.events = POLLIN;
rc = poll(&pfd, 1, timeout);
if (rc < 0) {
perror("poll");
return 0;
}
if (rc > 0) {
if (pfd.revents & POLLIN) {
rc = read(fd, buffer, count);
return rc;
}
}
return 0;
}
static int int_read_waitfor(int fd, uint8_t *buffer, size_t count, int timeout)
{
int rc;
struct timespec start, end;
int delta_ms;
int recv = 0;
do {
clock_gettime(CLOCK_MONOTONIC_RAW, &start);
rc = int_read_poll(fd, buffer + recv, count - recv, timeout);
clock_gettime(CLOCK_MONOTONIC_RAW, &end);
delta_ms = (end.tv_nsec - start.tv_nsec) / 1000000;
if (!rc || (rc < 0)) return 0;
recv += rc;
timeout -= delta_ms;
if (timeout <= 0)
return 0;
} while (recv != count);
return recv;
}
On a serial port, poll returns on each single byte and causes many iterations.
Is there a more elegant way to solve that problem?
I am aware that depending on the baudrate, timeout might not decrement in that code portion. Counting nanoseconds might be a better approach.
A simple solution might be to use alarm (if your timeout is in seconds) or setitimer with the ITIMER_REAL timer. Then just have the read call return with an error when the signal happens (with errno == EINTR)
Thanks to all for your valuable hints!
After some testing, I finally decided not to use signals as they may interfere with the application once I port my functions into a library or publish them as source.
I eventually found a neat solution which uses poll and termios (only four syscalls):
static int int_read_waitfor(int fd, uint8_t *buffer, size_t count, int timeout)
{
struct termios tm;
struct pollfd pfd;
int rc;
tcgetattr(fd, &tm);
tm.c_cc[VTIME] = 1; // inter-character timeout 100ms, valid after first char recvd
tm.c_cc[VMIN] = count; // block until n characters are read
tcsetattr(fd, TCSANOW, &tm);
pfd.fd = fd;
pfd.events = POLLIN;
rc = poll(&pfd, 1, timeout);
if (rc > 0) {
rc = read(fd, buffer, count);
if (rc == -1) {
perror("read");
return 0;
}
return rc;
}
return 0;
}
Unlike network sockets which are usually packet based, serial ports (n.b.: in non-canonical mode) are character based. It is expected that a loop with poll is iterated for every arriving character, in particular at low baud rates.
I my application I send a comand over a serial line to a device and wait for an answer.
If no answer is received, a timeout will occur and maybe we'll do a retry.
The termios option "VMIN" is handy as I can specify how many characters I like to reveive. Normally read would block until n chars have arrived.
If there is no answer, the command will block forever.
The termios option "VTIME" in conjunction with VMIN > 0 is specifying the intercharacter timeout in deciseconds (1 = 100ms). This is handy but the timeout will start only after reception of the first character. Otherwise an intercharacter timeout would make no sense.
So if I would use only termios options, read would block of the slave serial device is dead.
To circumvent that problem, I use poll in front of read.
Once the first character has arrived (poll returns with rc=1), I start reading. "VTIME" is active as well and will enforce the intercharacter time of 100ms (the lowest possible setting).
As a bonus the timeout handling is optimized:
Lets assume a timeout of 400ms
If the slave device is dead, poll will return after 400ms
If the slave works and replies within 50ms (first character), poll returns and read starts. If the slave sends too few data, VTIME will kick in and stop reception after 50ms + 100ms. We don't have to wait the whole 400ms for the last (missing) byte to arrive.
I have a C program that writes 32768 blocks, each block is 16K size (total size of 512MB), to an ext4 filesystem on a system running 3.18.1 kernel. The regular write system call version of this program takes 5.35 seconds to finish the writes (as measured by gettimeofday before and after the for loop). The async io version of this program however takes the following times:
to queue all the aio_writes (32768 aio_writes): 7.43 seconds
poll to finish each IO request: additional 4.93 seconds
The output files are opened with these flags:O_WRONLY, O_CREAT, O_NONBLOCK
Why does async io take more than double the write() time? Even the Time-to-queue-async-io-request/time-to-write-sync-io is 1.4.
Since some people marked it off-topic, I looked at the definition and decided to paste the code - that seems to be the only reason why it should be marked off-topic. I am not asking why the code is not working, only why aio is much slower than regular writes, especially since all parallel writes are to different blocks. Here's the aio code, followed by the non-aio code:
AIO program
#define MAX_AIO (16384*2)
#define BUFSIZE 16384
struct mys {
int status;
struct aiocb aio;
};
void set_aiocb(struct mys *aio, int num, int fd)
{
int i;
for (i = 0; i < num; i++) {
aio[i].aio.aio_fildes = fd;
aio[i].aio.aio_offset = BUFSIZE * i;
aio[i].aio.aio_buf = malloc(BUFSIZE);
set_buf(aio[i].aio.aio_buf, BUFSIZE, i);
aio[i].aio.aio_nbytes = BUFSIZE;
aio[i].aio.aio_reqprio = fd;
aio[i].aio.aio_sigevent.sigev_notify = SIGEV_NONE;
aio[i].aio.aio_sigevent.sigev_signo = SIGUSR1;
aio[i].aio.aio_sigevent.sigev_value.sival_ptr = &aio[i];
aio[i].aio.aio_lio_opcode = 0;
aio[i].status = EINPROGRESS;
}
}
void main(void)
{
int fd = open("/tmp/AIO", O_WRONLY | O_CREAT, 0666);
int i, open_reqs = MAX_AIO;
struct mys aio[MAX_AIO];
struct timeval start, end, diff;
set_aiocb(aio, MAX_AIO, fd);
gettimeofday(&start, NULL);
for (i = 0; i < MAX_AIO; i++)
aio_write(&aio[i].aio);
while (open_reqs > 0) {
for (i = 0; i < MAX_AIO; i++) {
if (aio[i].status == EINPROGRESS) {
aio[i].status = aio_error(&(aio[i].aio));
if (aio[i].status != EINPROGRESS)
open_reqs--;
}
}
}
gettimeofday(&end, NULL);
timersub(&end, &start, &diff);
printf("%d.%d\n", (int)diff.tv_sec, (int)diff.tv_usec);
}
Regular IO program
#define MAX_AIO (16384*2)
#define BUFSIZE 16384
char buf[MAX_AIO][BUFSIZE];
void main(void)
{
int i, fd = open("/tmp/NON_AIO", O_WRONLY | O_CREAT, 0666);
struct timeval start, end, diff;
gettimeofday(&start, NULL);
for (i = 0; i < MAX_AIO; i++)
write(fd, buf[i], BUFSIZE);
gettimeofday(&end, NULL);
timersub(&end, &start, &diff);
printf("%d.%d\n", (int)diff.tv_sec, (int)diff.tv_usec);
}
You aren't really comparing apples with apples.
In the AIO code, you have a separately allocated buffer for each of the write operations, so the program has 512 MiB (16 * 16 * 2 KiB) of memory allocated, plus the 32 K copies of the AIO control structure. That memory has to be allocated, initialized (each buffer gets a different value if the set_buf() function — which is not shown — sets each byte of the buffer to the value of the third parameter), then copied by the kernel to the driver, possibly via the kernel buffer pool.
In the regular IO code, you have one big, contiguous buffer which is initialized to all zeroes which you write to the disk.
To make the comparison equitable, you should use the same infrastructure in both programs, creating the AIO structures, but the regular IO code will then simply step through the structures, writing the data portion of each (while the AIO code will behave more or less as shown). And I expect you will find that the performance is a lot more nearly similar when you do that.
I need to capture some metrics such as time to send a tcp message and number of messages sent per second in c on linux.
I am wondering if this can be done via timer, such that whenever timer expires, i simply print the metrics. The main problem is that a timer can occur while metrics are being incremented and in that case, my signal handler would print corrupt data. Is there a way to over come this issue?
So the pseudo code in my mind was to declare a global struct which would contain send time for each send and count.
struct db
{
struct sendTimes sendTimesPerSecond[10000]; // some large number which i cannot send in a second
int count;
}
where
struct sendTimes
{
timeval start_time;
timeval end_time;
}
then provide few functions that would work on struct db such as
void record_send_time(pointer_to_db, sendTimes); // simply store the times
void incrementMessagesSent(pointer_to_db); //basically count++
Then i can do something like:-
signal(SIGALRM, alarm_handler);
alarm(1)
struct db database;
for(;;) {
struct sendTimes sTime;
sTime.start_time = now(); // current time
send()
sTime.end_time = now();
record_send_time(&database, sTime);
incrementMessagesSent(&database);
}
void alarm_handler(int signo)
{
printf database;
alarm(1);
}
UPDATE:
Wildplasser comment about pipe seems to be the safest way to handle the above issue.
You can use the alarm_handler to set a flag instead of printing from the signal handler.
int print_database_flag = 0; // global flag
// ...
record_send_time(&database, sTime);
if (print_database_flag) {
printf database;
print_database_flag = 0;
}
void alarm_handler(int signo)
{
print_database_flag = 1;
alarm(1);
}
Use getrusage(2) which has two struct timeval capturing time used up by our program in user (your code) and kernel mode (sends and the such).
#include <sys/time.h>
#include <sys/resource.h>
.
struct rusage start, end;
getrusage(RUSAGE_SELF, &start);
// do what you have to do
getrusage(RUSAGE_SELF, &end);
struct timeval utime, stime;
timersub(&end.ru_utime, &start.ru_utime, &utime);
timersub(&end.ru_stime, &start.ru_stime, &stime);
printf("Work took %lu microseconds of user time and %lu microseconds of system time\n",
(utime.tv_sec * 1000 * 1000) + utime.tv_usec,
(stime.tv_sec * 1000 * 1000) + stime.tv_usec
);