Tuesday, 28 May 2013

Time bomb in sequential process id allocation, what to do when the `unsigned` wraps?

Time bomb in sequential process id allocation, what to do when the `unsigned` wraps?

I'm designing and implementing a multiprocessing postscript interpreter, and I need to generate a unique identifier for each process in the system, as well as any dead processes which still have live references.
I've started with a simple increment, which arithmetically maps to the table index for the per-process data.
http://code.google.com/p/xpost/source/browse/itp.c#115
unsigned nextid = 0;  // global (file-static) counter

unsigned initctxid(void) {  // generate a new cid
    while ( ctxcid(++nextid)->state != 0 )  // .state == 0 means free
        ;
    return nextid;
}

context *ctxcid(unsigned cid) {  // get context data from cid
    return &itpdata.ctab[ (cid-1) % MAXCONTEXT ];
}
But there's gonna be a big problem if (when) the unsigned wraps around. Perhaps not scary for a game or an application, but this thing is supposed to be a server. Eventually. I'd like to avoid writing (in earnest) the disclaimer, "warning: will start having strange problems after running for a long time".
So, it should be easy enough to detect when it wraps, but what then? Bail out?
So the situation/scenario so far is: you're a multitasking postscript server with a handful of processes with cids allocated during one epoch of the generator, and the epoch has just turned. My thought (not impossible, just seems really hard) is to compact these existing IDs down to the 0..N range (rewriting all references, scanning all memory if necessary) and reset nextid to N.
But that's gonna be a pain-in-the-butt. Is there a different way to generate these IDs so I don't have to do a big garbage-collect on them, and have it work, you know, perpetually?

No comments:

Post a Comment