Talk About Network

Google


Register and Login
Nick
Password
Register create new account Sign up is FREE and you can post replies, new topics, bookmark posts and more!
Recover lost password


Programming > Programming Threads > One-time initia...
Latest [ Topics | Posts ] Archive Post A New Topic Post a Reply
<< Topic < Post Post 1 of 9 Topic 4079 of 4146
Post > Topic >>

One-time initialization template optimization

by Brian Cole <coleb2@[EMAIL PROTECTED] > Oct 10, 2008 at 11:23 AM

The following is a convenience class for wrapping up the
initialization of an arbitrary object into a function local static. It
relys on pthread_once and the pthread thread local storage API. The
pthread thread local storage is wrapped into its own convenience class
ThreadLocal<>. If anyone thinks they need that as well I'd be happy to
share it.

template<class T>
class OnceHelper
{
  T **_ptr;
public:
  OnceHelper() : _ptr(0) {}
  inline void Set(T **ptr) { _ptr = ptr; }
  inline T **Get() { return _ptr; }
};

template<class T>
struct Once
{
  T *_obj;
  pthread_once_t _once;

  // ThreadLocal will construct and destruct during single-threaded
  // program startup and teardown
  static ThreadLocal<OEOnceHelper<T> > _tls;
  static void Init()
  {
    T **ptr = _tls->Get();
    assert(ptr != 0);
    *ptr = new T;
  }

  inline T *GetValue()
  {
    _tls->Set(&_obj);
    if (pthread_once(&_once, Init) != 0)
      perror("Problem with pthread_once");

    return _obj;
  }

  ~Once() { delete _obj; }
  inline T& operator *() { return *GetValue(); }
  inline T* operator ->() { return GetValue(); }
  inline operator T* () { return operator ->(); }
};
#define ONCE_INIT { 0, PTHREAD_ONCE_INIT }
template<class T> ThreadLocal<OnceHelper<T> > Once<T>::_tls;

The usage looks something like this then:
void Foo()
{
  static Once<Mutex> mutex = ONCE_INIT;
  Lock lock(*mutex);
  // do something thread-safely
}

My question deals with the GetValue workhorse method in the class.
Adding the following optimization where I check the _obj pointer
against being NULL can gain me as much as %10 in one of my
applications.
  inline T *GetValue()
  {
    if (!_obj)
    {
      _tls->Set(&_obj);
      if (pthread_once(&_once, Init) != 0)
        perror("Problem with pthread_once");
    }

    return _obj;
  }

The assumption is atomic pointer assignment on x86, x64, PPC, Sparc,
IA64 (the architectures I need to sup****t). If this isn't the case on
one of these, please let me know so I can ifdef the optimization out.
I'm almost tempted to say it's thread-safe "enough", but I know that
is asking for trouble. Any other optimizations some may see? I have an
equivalent class using Win32 intrinsics if anyone is interested as
well.

Thanks,
Brian
 




 9 Posts in Topic:
One-time initialization template optimization
Brian Cole <coleb2@[EM  2008-10-10 11:23:57 
Re: One-time initialization template optimization
"Chris M. Thomasson&  2008-10-10 12:24:39 
Re: One-time initialization template optimization
"Chris M. Thomasson&  2008-10-10 13:11:42 
Re: One-time initialization template optimization
"Chris M. Thomasson&  2008-10-10 13:44:41 
Re: One-time initialization template optimization
Brian Cole <coleb2@[EM  2008-10-10 14:41:20 
Re: One-time initialization template optimization
"Chris M. Thomasson&  2008-10-11 00:48:53 
Re: One-time initialization template optimization
"Chris M. Thomasson&  2008-10-11 01:00:07 
Re: One-time initialization template optimization
Brian Cole <coleb2@[EM  2008-10-11 06:34:15 
Re: One-time initialization template optimization
"Chris M. Thomasson&  2008-10-13 10:35:10 

Post A Reply:
  Go here to Signup

AddThis Feed Button


About - Advertising - Contact - Frequently Asked Questions - Privacy Policy - Terms of Use - Signup

Contact
tan12V112 Sat Nov 22 9:33:05 CST 2008.