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''' * Advancing the ''clock'' is fast - a single increment of an integer variable * Checking the lock is slightly slower than a simple flag - it requires comparing two integer variables. However, this is still quite fast. * This pattern only works for unlocking either a single object or ''everything'' - it isn't selective * It's less error prone than individually tracking ''locked'' objects - you can't ''miss'' any. '''Known Uses''' I've used this pattern for a number of things. * In an interpreter with a copying garbage collector: During the interpretation of an instruction, various memory blocks would be locked so they wouldn't be moved. At the end of the instruction (a ''safe'' point) they could all be unlocked by simply advancing the clock. * For cache validity, when objects cache calculated values that some external event can invalidate. In this case, it's not really a ''lock'', it's a ''cache-valid'' flag. The invalidate can just advance the clock, whereafter ''cache-valid'' on all the objects will be false. 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 ----