From 3186d00cffe9fc7b8290344ab4ae23fab681942c Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 4 Mar 2010 08:51:30 +0000 Subject: [PATCH] Builds now on Win32 too. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@11063 --- drd/tests/annotate_smart_pointer.cpp | 184 +++++++++++++++++++++++---- 1 file changed, 159 insertions(+), 25 deletions(-) diff --git a/drd/tests/annotate_smart_pointer.cpp b/drd/tests/annotate_smart_pointer.cpp index 90dd023bbd..61532d3c36 100755 --- a/drd/tests/annotate_smart_pointer.cpp +++ b/drd/tests/annotate_smart_pointer.cpp @@ -1,13 +1,151 @@ #include #include +#ifdef _WIN32 +#include +#include +#else #include #include +#endif + +#ifdef _WIN32 +class AtomicInt32 +{ +public: + AtomicInt32(const int value = 0) : m_value(value) { } + ~AtomicInt32() { } + LONG operator++() { return InterlockedIncrement(&m_value); } + LONG operator--() { return InterlockedDecrement(&m_value); } + +private: + volatile LONG m_value; +}; + +class Mutex +{ +public: + Mutex() : m_mutex() + { InitializeCriticalSection(&m_mutex); } + ~Mutex() + { DeleteCriticalSection(&m_mutex); } + void Lock() + { EnterCriticalSection(&m_mutex); } + void Unlock() + { LeaveCriticalSection(&m_mutex); } + +private: + CRITICAL_SECTION m_mutex; +}; + +class Semaphore +{ +public: + Semaphore() + : m_sem(CreateSemaphore(NULL, 0, 1, NULL)) + { assert(m_sem != INVALID_HANDLE_VALUE); } + ~Semaphore() + { CloseHandle(m_sem); } + void Post() const + { ReleaseSemaphore(m_sem, 1, NULL); } + void Wait() const + { WaitForSingleObject(m_sem, INFINITE); } +private: + const HANDLE m_sem; +}; + +class Thread +{ +public: + Thread() : m_thread(INVALID_HANDLE_VALUE) { } + ~Thread() { } + void Create(void* (*pf)(void*), void* arg) + { + wrapper_args* wrapper_arg_p = new wrapper_args(pf, arg); + m_thread = reinterpret_cast(_beginthreadex(NULL, 0, wrapper, wrapper_arg_p, 0, NULL)); + } + void Join() + { WaitForSingleObject(m_thread, INFINITE); } + +private: + struct wrapper_args + { + wrapper_args(void* (*pf)(void*), void* arg) : m_pf(pf), m_arg(arg) { } + + void* (*m_pf)(void*); + void* m_arg; + }; + static unsigned int __stdcall wrapper(void* arg) + { + wrapper_args* wrapper_arg_p = reinterpret_cast(arg); + wrapper_args wa = *wrapper_arg_p; + delete wrapper_arg_p; + return reinterpret_cast((wa.m_pf)(wa.m_arg)); + } + HANDLE m_thread; +}; +#else // _WIN32 +class AtomicInt32 +{ +public: + AtomicInt32(const int value = 0) : m_value(value) { } + ~AtomicInt32() { } + int operator++() { return __sync_add_and_fetch(&m_value, 1); } + int operator--() { return __sync_sub_and_fetch(&m_value, 1); } +private: + volatile int m_value; +}; + +class Mutex +{ +public: + Mutex() : m_mutex() + { pthread_mutex_init(&m_mutex, NULL); } + ~Mutex() + { pthread_mutex_destroy(&m_mutex); } + void Lock() + { pthread_mutex_lock(&m_mutex); } + void Unlock() + { pthread_mutex_unlock(&m_mutex); } + +private: + pthread_mutex_t m_mutex; +}; + +class Semaphore +{ +public: + Semaphore() : m_sem() + { sem_init(&m_sem, 0, 0); } + ~Semaphore() + { sem_destroy(&m_sem); } + void Post() + { sem_post(&m_sem); } + void Wait() + { sem_wait(&m_sem); } +private: + sem_t m_sem; +}; + +class Thread +{ +public: + Thread() : m_tid() { } + ~Thread() { } + void Create(void* (*pf)(void*), void* arg) + { pthread_create(&m_tid, NULL, pf, arg); } + void Join() + { pthread_join(m_tid, NULL); } +private: + pthread_t m_tid; +}; +#endif // _WIN32 + template class smart_ptr { public: - typedef unsigned counter_t; + typedef AtomicInt32 counter_t; template friend class smart_ptr; @@ -78,11 +216,11 @@ public: } private: - void set(T* const pT, volatile counter_t* const count_ptr) + void set(T* const pT, counter_t* const count_ptr) { if (m_ptr != pT) { - if (m_count_ptr && __sync_sub_and_fetch(m_count_ptr, 1) == 0) + if (m_count_ptr && --(*m_count_ptr) == 0) { delete m_ptr; delete m_count_ptr; @@ -90,12 +228,12 @@ private: m_ptr = pT; m_count_ptr = count_ptr; if (count_ptr) - __sync_add_and_fetch(count_ptr, 1); + ++(*m_count_ptr); } } - T* m_ptr; - volatile counter_t* m_count_ptr; + T* m_ptr; + counter_t* m_count_ptr; }; class counter @@ -104,41 +242,37 @@ public: counter() : m_mutex(), m_count() { - pthread_mutex_init(&m_mutex, NULL); } ~counter() - { - m_count = -1; - pthread_mutex_destroy(&m_mutex); - } + { m_count = -1; } int get() const { int result; - pthread_mutex_lock(&m_mutex); + m_mutex.Lock(); result = m_count; - pthread_mutex_unlock(&m_mutex); + m_mutex.Unlock(); return result; } int post_increment() { int result; - pthread_mutex_lock(&m_mutex); + m_mutex.Lock(); result = m_count++; - pthread_mutex_unlock(&m_mutex); + m_mutex.Unlock(); return result; } private: - mutable pthread_mutex_t m_mutex; - int m_count; + mutable Mutex m_mutex; + int m_count; }; -static sem_t s_sem; +static Semaphore* s_sem; static void* thread_func(void* arg) { smart_ptr p(*reinterpret_cast*>(arg)); - sem_post(&s_sem); + s_sem->Post(); p->post_increment(); p = NULL; return NULL; @@ -147,16 +281,16 @@ static void* thread_func(void* arg) int main(int argc, char** argv) { smart_ptr p(new counter); - pthread_t tid; + Thread T; - sem_init(&s_sem, 0, 0); + s_sem = new Semaphore(); p->post_increment(); - pthread_create(&tid, NULL, thread_func, &p); + T.Create(thread_func, &p); // Wait until the created thread has copied the shared pointer. - sem_wait(&s_sem); + s_sem->Wait(); p = NULL; - pthread_join(tid, NULL); - sem_destroy(&s_sem); + T.Join(); + delete s_sem; std::cout << "Done.\n"; return 0; } -- 2.47.2