Re: A real threaded singleton
<EvilOldGit@googlemail.com> wrote in message
news:1176139389.896023.61590@n76g2000hsh.googlegroups.com...
In the stuff I've read about multi threaded singleton it seems to
assume that creating the Lock is atomic, and various sources,
including Sutter go for RAII.
There is a solution for a thread-safe version of that here:
http://groups.google.com/group/comp.programming.threads/browse_frm/thread/6da701564880ab4
http://appcore.home.comcast.net/vzdoc/atomic/static-init/
http://appcore.home.comcast.net/vzoom/refcount/
You use a hashed-mutex/spinlock scheme to handle atomic lock
construction/destruction. e.g.:
// Details
#define DETAIL_CONCATX(__t1, __t2)__t1##__t2
#define DETAIL_CONCAT(__t1, __t2)CONCATX(__t1, __t2)
#define DETAIL_HASHMUTEX_8(__init) __init, __init, __init, __init, __init, __init, __init, __init
#define DETAIL_HASHMUTEX_32(__init) DETAIL_HASHMUTEX_8(__init), DETAIL_HASHMUTEX_8(__init), DETAIL_HASHMUTEX_8(__init), DETAIL_HASHMUTEX_8(__init)
#define DETAIL_HASHMUTEX_128(__init) DETAIL_HASHMUTEX_32(__init), DETAIL_HASHMUTEX_32(__init), DETAIL_HASHMUTEX_32(__init), DETAIL_HASHMUTEX_32(__init)
#define DETAIL_HASHMUTEX_256(__init) DETAIL_HASHMUTEX_128(__init), DETAIL_HASHMUTEX_128(__init)
#define DETAIL_HASHMUTEX_512(__init) DETAIL_HASHMUTEX_256(__init), DETAIL_HASHMUTEX_256(__init)
#define DETAIL_HASHMUTEX_CONCAT(__init, __count) DETAIL_CONCAT(DETAIL_HASHMUTEX_, __count)(__init)
// Impl
#include <pthread.h>
#define HASHMUTEX_DEPTH() 256
#define HASHMUTEX_INITIALIZER() PTHREAD_MUTEX_INITIALIZER
#define HASHMUTEX_PTR(__ptr) (((int)__ptr) % HASHMUTEX_DEPTH())
#define HASHMUTEX_STATICINIT() { DETAIL_HASHMUTEX_CONCAT(HASHMUTEX_INITIALIZER(), HASHMUTEX_DEPTH()) }
// hashed-mutex table
static pthread_mutex_t hashmutex_table[
HASHMUTEX_DEPTH()
] = HASHMUTEX_STATICINIT();
static int hashmutex_lock(void* const ptr) {
return pthread_mutex_lock(&hashmutex_table[HASHMUTEX_PTR(ptr)]);
}
static int hashmutex_trylock(void* const ptr) {
return pthread_mutex_trylock(&hashmutex_table[HASHMUTEX_PTR(ptr)]);
}
static int hashmutex_unlock(void* const ptr) {
return pthread_mutex_unlock(&hashmutex_table[HASHMUTEX_PTR(ptr)]);
}
class A {};
class B {};
static A g_a;
static B g_b;
int main() {
// lock & unlock a
hashmutex_lock(&g_a);
// ...
hashmutex_unlock(&g_a);
// lock & unlock b
hashmutex_lock(&g_b);
// ...
hashmutex_unlock(&g_b);
return 0;
}
Got to watch out for deadlocks... Here is one possible solution:
http://groups.google.com/group/comp.programming.threads/browse_frm/thread/e0c011baf08844c4/
Any thoughts?
:^)