Clock Lock

This seems like such a simple, obvious pattern that I've got to think it's known, but I haven't come across it anywhere yet.

Intent

Provide an efficient way to unlock a number of objects, without having to keep a list of the objects.

Code

 class
{
static int clock;
int lock_clock;
void lock()
{ lock_clock = clock; }
bool is_locked()
{ return lock_clock == clock; }
void unlock()
{ --lock_clock; }
static void unlock_all()
{ ++clock; }
}
Consequences

Known Uses

I've used this pattern for a number of things.

I realize that's not the recommended three uses - can anyone add another?

AndrewMcKinlay - http://www.suneido.com


As indicated by your second example, the applicability of this pattern is more generic than "locking". It's more like a way of associating a set of objects with a particular snapshot or UnitOfWork, where the "clock" variable is really a "current operation ID" value.

Concur. This seems more an example of a simple semaphore locking system than a pattern. Real time OSes have had this capability for eons. Most real time systems are built around some permutation of this.


You could be right, perhaps it's too simple and obvious to be a pattern. On the other hand, I haven't seen this technique applied to this type of usage anywhere. And isn't that one of the signs of a good pattern - that everyone says "well, yeah, that's obvious". :-)

I agree--this is generic and has wide applicability. I'd like to see more of these low-level techniques described as patterns. But it needs a different name than "Clock Lock", because its applicability goes beyond "clocks" and "locks".


* This pattern only works for unlocking everything - it isn't selective'

Couldn't you provide a single unlock like this:

void unlock()
{ --lock_clock; }
That could work, as long as having "wrong" lock_clock values is not going to lead to any errors. But if some other thread or another part of the logic expects lock_clock to actually contain the clock value for when it was last locked, then this is a problem.

This brings up another consequence--how do you handle overflow (or underflow) of the counter?


Good point, I have used unlock like that. I've updated the code and description.

Overflow/underflow is a potential problem. For a lot of my uses, it would take years before the counter wrapped around (a 32 bit int is big!), in which case I can ignore the issue. But if you were using it in a situation where it was called a lot then you'd want to handle it.

Use 64 bit values. I doubt you can run out of those.

Anyone have a suggestion for a better name than ClockLock?

The name led me to believe a clock would be involved. All I see is a sequence. Perhaps SequentialLock??

Maybe SemaphoreWithGroupInvalidate?? -- AdamBerger



EditText of this page (last edited November 3, 2003) or FindPage with title or text search