Re: Issues in generating unique time id using virtual memory address
On Sun, 2012-06-10, ittium wrote:
Group,
I came across a timer implementation where to generate unique timer id,
implementer has used virtual memory address. In the program written
below, using new, 1 byte memory is allocated, this memory is kept
reserved till timer expiry. Since this address will be unique (in
program virtual memory), uniqueness of timer id is guaranteed.
You can skip all the talk about virtual memory. C++ doesn't care
about that. It simply guarantees that
T* const a = new T();
T* const b = new T();
assert(a!=b);
for as long as *a and *b exist.
This code
is used in a multi-threaded program and is supposed to generate unique
ids on 32bit and 64bit machines. The code always work fine during unit
testing. But in field trials (code running for more than a month or so)
, some time, we have seen on a 32 bit machine code generates junk
timerId. I doubt a possible heap corruption, but we can not run memory
profilers in field trials. Please go through the code. I have added my
comments, where I think code might have some issue.
#include <iostream>
#include <stdlib.h>
using namespace std;
typedef uint64_t BYTE8;
What a weird typedef! What's wrong with uint64_t?
typedef unsigned char BYTE;
#define _AAANEW(ptr,structClass) \
try \
{ \
ptr = NULL; // Comment - not needed but see the catch block
ptr = new structClass; \
} \
catch(...) \
{ \
if(ptr == NULL) \
{ \
cout<<"Failure in _AAANEW, exiting the process";\
exit(0); \
} \
}
Ugh. I won't comment on that ...
BYTE8 getTimerId()
{
BYTE* timer;
_AAANEW(timer,BYTE); //Comment - On 32 bit machine, timer will
//contain 32 bit virtual memory address
/* Timer id is taken as BYTE 8 since timer Id will be generated
on 32 bit an 64 bit also */
BYTE8 timerId = (BYTE8)timer; //Comment - I am not sure
// whether for 32 bit machine this
//conversion is safe
return timerId;
}
OK, so yo allocate an ID by new:ing a small object, cast its address
to uint64_t, and that's the ID. Presumably you never delete that
small object? I see nothing wrong with it on systems with flat
addresses less than or equal 64-bits. I think your bug is elsewhere.
By the way, why don't you just say "the timer ID is an unsigned
char*"? Why bother to squeeze it into an integer?
/Jorgen
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .