Developing a Lightweight, Statically Initializable C++ Mutex
by Vladimir Kliatchko 

Listing One

class Singleton {
    Singleton();
    ~Singleton();
  public:
    static Singleton& instance();
};

Singleton& Singleton::instance() {
    static Singleton singleton;
    return singleton;
}


Listing Two

class Singleton {
    Singleton();
    ~Singleton();
    static Singleton *s_singleton;
    static void init();
  public:
    static Singleton& instance();
};
Singleton *Singleton::s_singleton = 0;
void Singleton::init() {
    static Singleton singleton;
    s_singleton = &singleton;
}
Singleton& Singleton::instance() {
    lock(&mutex);
    if (!s_singleton) {
        init();
    }
    unlock(&mutex);
    return *s_singleton;
}


Listing Three

Singleton& Singleton::instance() {
    static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    pthread_mutex_lock(&mutex);
    if (!s_singleton) {
        init();
    }
    pthread_mutex_unlock(&mutex);
    return *s_singleton;
}

Listing Four

Singleton& Singleton::instance() {
    static pthread_once_t once_control = PTHREAD_ONCE_INIT;
    pthread_once(&once_control, &Singleton::init);
    return *s_singleton;
}

Listing Five

Singleton& Singleton::instance() {
    static volatile LONG lock = 0;
    while (InterlockedExchange(&lock, 1) != 0) {
        Sleep(1);
    }
    if (!s_singleton) {
        init();
    }
    InterlockedExchange(&lock, 0);
    return *s_singleton;
}


Listing Six

Singleton& Singleton::instance() {
    static volatile LONG control = 0;
    while (1) {
        LONG prev = InterlockedCompareExchange(&control, 1, 0);
        if (2 == prev) {
            // The singleton has been initialized.
            return *s_singleton;
        }
        elsif (0 == prev) {
            // got the lock
            break;
        }
        else {
            // Another thread is initializing the singleton:
            // must wait.
            assert(1 == prev);
            Sleep(1); // sleep 1 millisecond
        }
    }
    if (!s_singleton) {
        init();
    }
    InterlockedExchange(&control, 2);
    return *s_singleton;
}



2


