mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-08 21:09:49 +00:00
Builds now on Win32 too.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@11063
This commit is contained in:
@@ -1,13 +1,151 @@
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#ifdef _WIN32
|
||||
#include <process.h>
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#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<HANDLE>(_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<wrapper_args*>(arg);
|
||||
wrapper_args wa = *wrapper_arg_p;
|
||||
delete wrapper_arg_p;
|
||||
return reinterpret_cast<unsigned>((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 T>
|
||||
class smart_ptr
|
||||
{
|
||||
public:
|
||||
typedef unsigned counter_t;
|
||||
typedef AtomicInt32 counter_t;
|
||||
|
||||
template <typename Q> 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<counter> p(*reinterpret_cast<smart_ptr<counter>*>(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<counter> 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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user