mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-08 21:09:49 +00:00
Added the source code of one more unit test.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@11059
This commit is contained in:
162
drd/tests/annotate_smart_pointer.cpp
Executable file
162
drd/tests/annotate_smart_pointer.cpp
Executable file
@@ -0,0 +1,162 @@
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
|
||||
template<class T>
|
||||
class smart_ptr
|
||||
{
|
||||
public:
|
||||
typedef unsigned counter_t;
|
||||
|
||||
template <typename Q> friend class smart_ptr;
|
||||
|
||||
explicit smart_ptr()
|
||||
: m_ptr(NULL), m_count_ptr(NULL)
|
||||
{ }
|
||||
|
||||
explicit smart_ptr(T* const pT)
|
||||
: m_ptr(NULL), m_count_ptr(NULL)
|
||||
{
|
||||
set(pT, pT ? new counter_t(0) : NULL);
|
||||
}
|
||||
|
||||
template <typename Q>
|
||||
explicit smart_ptr(Q* const q)
|
||||
: m_ptr(NULL), m_count_ptr(NULL)
|
||||
{
|
||||
set(q, q ? new counter_t(0) : NULL);
|
||||
}
|
||||
|
||||
~smart_ptr()
|
||||
{
|
||||
set(NULL, NULL);
|
||||
}
|
||||
|
||||
smart_ptr(const smart_ptr<T>& sp)
|
||||
: m_ptr(NULL), m_count_ptr(NULL)
|
||||
{
|
||||
set(sp.m_ptr, sp.m_count_ptr);
|
||||
}
|
||||
|
||||
template <typename Q>
|
||||
smart_ptr(const smart_ptr<Q>& sp)
|
||||
: m_ptr(NULL), m_count_ptr(NULL)
|
||||
{
|
||||
set(sp.m_ptr, sp.m_count_ptr);
|
||||
}
|
||||
|
||||
smart_ptr& operator=(const smart_ptr<T>& sp)
|
||||
{
|
||||
set(sp.m_ptr, sp.m_count_ptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
smart_ptr& operator=(T* const p)
|
||||
{
|
||||
set(p, p ? new counter_t(0) : NULL);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename Q>
|
||||
smart_ptr& operator=(Q* const q)
|
||||
{
|
||||
set(q, q ? new counter_t(0) : NULL);
|
||||
return *this;
|
||||
}
|
||||
|
||||
T* operator->() const
|
||||
{
|
||||
assert(m_ptr);
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
T& operator*() const
|
||||
{
|
||||
assert(m_ptr);
|
||||
return *m_ptr;
|
||||
}
|
||||
|
||||
private:
|
||||
void set(T* const pT, volatile counter_t* const count_ptr)
|
||||
{
|
||||
if (m_ptr != pT)
|
||||
{
|
||||
if (m_count_ptr && __sync_sub_and_fetch(m_count_ptr, 1) == 0)
|
||||
{
|
||||
delete m_ptr;
|
||||
delete m_count_ptr;
|
||||
}
|
||||
m_ptr = pT;
|
||||
m_count_ptr = count_ptr;
|
||||
if (count_ptr)
|
||||
__sync_add_and_fetch(count_ptr, 1);
|
||||
}
|
||||
}
|
||||
|
||||
T* m_ptr;
|
||||
volatile counter_t* m_count_ptr;
|
||||
};
|
||||
|
||||
class counter
|
||||
{
|
||||
public:
|
||||
counter()
|
||||
: m_mutex(), m_count()
|
||||
{
|
||||
pthread_mutex_init(&m_mutex, NULL);
|
||||
}
|
||||
~counter()
|
||||
{
|
||||
m_count = -1;
|
||||
pthread_mutex_destroy(&m_mutex);
|
||||
}
|
||||
int get() const
|
||||
{
|
||||
int result;
|
||||
pthread_mutex_lock(&m_mutex);
|
||||
result = m_count;
|
||||
pthread_mutex_unlock(&m_mutex);
|
||||
return result;
|
||||
}
|
||||
int post_increment()
|
||||
{
|
||||
int result;
|
||||
pthread_mutex_lock(&m_mutex);
|
||||
result = m_count++;
|
||||
pthread_mutex_unlock(&m_mutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
mutable pthread_mutex_t m_mutex;
|
||||
int m_count;
|
||||
};
|
||||
|
||||
static sem_t s_sem;
|
||||
|
||||
static void* thread_func(void* arg)
|
||||
{
|
||||
smart_ptr<counter> p(*reinterpret_cast<smart_ptr<counter>*>(arg));
|
||||
sem_post(&s_sem);
|
||||
p->post_increment();
|
||||
p = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
smart_ptr<counter> p(new counter);
|
||||
pthread_t tid;
|
||||
|
||||
sem_init(&s_sem, 0, 0);
|
||||
p->post_increment();
|
||||
pthread_create(&tid, NULL, thread_func, &p);
|
||||
// Wait until the created thread has copied the shared pointer.
|
||||
sem_wait(&s_sem);
|
||||
p = NULL;
|
||||
pthread_join(tid, NULL);
|
||||
sem_destroy(&s_sem);
|
||||
std::cout << "Done.\n";
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user