2006-06-08 21:03:43 +02:00
|
|
|
#include "lib/self_test.h"
|
2006-05-31 06:17:45 +02:00
|
|
|
|
|
|
|
#include "lib/lockfree.h"
|
2006-06-22 20:26:08 +02:00
|
|
|
#include "lib/sysdep/cpu.h" // atomic_add
|
2006-06-08 21:03:43 +02:00
|
|
|
#include "lib/timer.h"
|
2007-05-18 02:14:26 +02:00
|
|
|
#include "lib/rand.h"
|
2006-05-31 06:17:45 +02:00
|
|
|
|
|
|
|
// make sure the data structures work at all; doesn't test thread-safety.
|
|
|
|
class TestLockfreeBasic : public CxxTest::TestSuite
|
|
|
|
{
|
|
|
|
public:
|
2008-07-17 19:00:00 +02:00
|
|
|
// note: the lockfree module is no longer part of the build, but cxxtestgen
|
|
|
|
// still sees this class and its methods despite them being commented out
|
|
|
|
// (#if 0 doesn't help, either). we therefore need to disable their bodies.
|
|
|
|
#if 0
|
2007-05-26 19:56:38 +02:00
|
|
|
void setUp()
|
|
|
|
{
|
|
|
|
lockfree_Init();
|
|
|
|
}
|
|
|
|
|
|
|
|
void tearDown()
|
|
|
|
{
|
|
|
|
lockfree_Shutdown();
|
|
|
|
}
|
2008-07-17 19:00:00 +02:00
|
|
|
#endif
|
2007-05-26 19:56:38 +02:00
|
|
|
|
2006-05-31 06:17:45 +02:00
|
|
|
void test_basic_single_threaded()
|
|
|
|
{
|
2008-07-17 19:00:00 +02:00
|
|
|
#if 0
|
2006-05-31 06:17:45 +02:00
|
|
|
void* user_data;
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
const size_t ENTRIES = 50;
|
2006-05-31 06:17:45 +02:00
|
|
|
// should be more than max # retired nodes to test release..() code
|
|
|
|
uintptr_t key = 0x1000;
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
size_t sig = 10;
|
2006-05-31 06:17:45 +02:00
|
|
|
|
|
|
|
LFList list;
|
|
|
|
TS_ASSERT_OK(lfl_init(&list));
|
|
|
|
|
|
|
|
LFHash hash;
|
|
|
|
TS_ASSERT_OK(lfh_init(&hash, 8));
|
|
|
|
|
|
|
|
// add some entries; store "signatures" (ascending int values)
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
for(size_t i = 0; i < ENTRIES; i++)
|
2006-05-31 06:17:45 +02:00
|
|
|
{
|
|
|
|
int was_inserted;
|
|
|
|
|
2006-06-08 23:27:03 +02:00
|
|
|
user_data = lfl_insert(&list, key+i, sizeof(int), &was_inserted);
|
2006-05-31 06:17:45 +02:00
|
|
|
TS_ASSERT(user_data != 0 && was_inserted);
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
*(size_t*)user_data = sig+i;
|
2006-05-31 06:17:45 +02:00
|
|
|
|
|
|
|
user_data = lfh_insert(&hash, key+i, sizeof(int), &was_inserted);
|
|
|
|
TS_ASSERT(user_data != 0 && was_inserted);
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
*(size_t*)user_data = sig+i;
|
2006-05-31 06:17:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// make sure all "signatures" are present in list
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
for(size_t i = 0; i < ENTRIES; i++)
|
2006-05-31 06:17:45 +02:00
|
|
|
{
|
2006-06-08 23:27:03 +02:00
|
|
|
user_data = lfl_find(&list, key+i);
|
2006-05-31 06:17:45 +02:00
|
|
|
TS_ASSERT(user_data != 0);
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
TS_ASSERT_EQUALS(*(size_t*)user_data, sig+i);
|
2006-05-31 06:17:45 +02:00
|
|
|
|
|
|
|
user_data = lfh_find(&hash, key+i);
|
|
|
|
TS_ASSERT(user_data != 0);
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
TS_ASSERT_EQUALS(*(size_t*)user_data, sig+i);
|
2006-05-31 06:17:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
lfl_free(&list);
|
|
|
|
lfh_free(&hash);
|
2008-07-17 19:00:00 +02:00
|
|
|
#endif
|
2006-05-31 06:17:45 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// known to fail on P4 due to mem reordering and lack of membars.
|
|
|
|
class TestMultithread : public CxxTest::TestSuite
|
|
|
|
{
|
2008-07-17 19:00:00 +02:00
|
|
|
#if 0
|
2007-05-26 19:56:38 +02:00
|
|
|
void setUp()
|
|
|
|
{
|
|
|
|
lockfree_Init();
|
|
|
|
}
|
|
|
|
|
|
|
|
void tearDown()
|
|
|
|
{
|
|
|
|
lockfree_Shutdown();
|
|
|
|
}
|
|
|
|
|
2006-05-31 06:17:45 +02:00
|
|
|
// poor man's synchronization "barrier"
|
|
|
|
bool is_complete;
|
|
|
|
intptr_t num_active_threads;
|
|
|
|
|
|
|
|
LFList list;
|
|
|
|
LFHash hash;
|
|
|
|
|
|
|
|
typedef std::set<uintptr_t> KeySet;
|
|
|
|
typedef KeySet::const_iterator KeySetIt;
|
|
|
|
KeySet keys;
|
|
|
|
pthread_mutex_t mutex; // protects <keys>
|
|
|
|
|
2006-06-08 21:03:43 +02:00
|
|
|
struct ThreadFuncParam
|
|
|
|
{
|
|
|
|
TestMultithread* this_;
|
|
|
|
uintptr_t thread_number;
|
|
|
|
|
|
|
|
ThreadFuncParam(TestMultithread* this__, uintptr_t thread_number_)
|
|
|
|
: this_(this__), thread_number(thread_number_) {}
|
|
|
|
};
|
|
|
|
|
2006-05-31 06:17:45 +02:00
|
|
|
static void* thread_func(void* arg)
|
|
|
|
{
|
2008-09-27 12:05:11 +02:00
|
|
|
debug_SetThreadName("LF_test");
|
2006-05-31 06:17:45 +02:00
|
|
|
|
2006-06-08 21:03:43 +02:00
|
|
|
ThreadFuncParam* param = (ThreadFuncParam*)arg;
|
|
|
|
TestMultithread* this_ = param->this_;
|
|
|
|
const uintptr_t thread_number = param->thread_number;
|
2006-05-31 06:17:45 +02:00
|
|
|
|
2007-05-03 17:42:43 +02:00
|
|
|
cpu_AtomicAdd(&this_->num_active_threads, 1);
|
2006-05-31 06:17:45 +02:00
|
|
|
|
|
|
|
// chosen randomly every iteration (int_value % 4)
|
|
|
|
enum TestAction
|
|
|
|
{
|
|
|
|
TA_FIND = 0,
|
|
|
|
TA_INSERT = 1,
|
|
|
|
TA_ERASE = 2,
|
|
|
|
TA_SLEEP = 3
|
|
|
|
};
|
|
|
|
static const char* const action_strings[] =
|
|
|
|
{
|
|
|
|
"find", "insert", "erase", "sleep"
|
|
|
|
};
|
|
|
|
|
2006-06-08 21:03:43 +02:00
|
|
|
while(!this_->is_complete)
|
2006-05-31 06:17:45 +02:00
|
|
|
{
|
|
|
|
void* user_data;
|
|
|
|
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
const size_t action = rand(0, 4);
|
|
|
|
const uintptr_t key = (uintptr_t)rand(0, 100);
|
|
|
|
const size_t sleep_duration_ms = rand(0, 100);
|
2006-05-31 06:17:45 +02:00
|
|
|
debug_printf("thread %d: %s\n", thread_number, action_strings[action]);
|
|
|
|
|
|
|
|
//
|
2006-06-08 21:03:43 +02:00
|
|
|
pthread_mutex_lock(&this_->mutex);
|
|
|
|
const bool was_in_set = this_->keys.find(key) != this_->keys.end();
|
2006-05-31 06:17:45 +02:00
|
|
|
if(action == TA_INSERT)
|
2006-06-08 21:03:43 +02:00
|
|
|
this_->keys.insert(key);
|
2006-05-31 06:17:45 +02:00
|
|
|
else if(action == TA_ERASE)
|
2006-06-08 21:03:43 +02:00
|
|
|
this_->keys.erase(key);
|
|
|
|
pthread_mutex_unlock(&this_->mutex);
|
2006-05-31 06:17:45 +02:00
|
|
|
|
|
|
|
switch(action)
|
|
|
|
{
|
|
|
|
case TA_FIND:
|
|
|
|
{
|
2006-06-08 21:03:43 +02:00
|
|
|
user_data = lfl_find(&this_->list, key);
|
2006-05-31 06:17:45 +02:00
|
|
|
TS_ASSERT(was_in_set == (user_data != 0));
|
|
|
|
if(user_data)
|
2006-06-08 00:15:29 +02:00
|
|
|
TS_ASSERT_EQUALS(*(uintptr_t*)user_data, ~key);
|
2006-05-31 06:17:45 +02:00
|
|
|
|
2006-06-08 21:03:43 +02:00
|
|
|
user_data = lfh_find(&this_->hash, key);
|
2006-05-31 06:17:45 +02:00
|
|
|
// typical failure site if lockfree data structure has bugs.
|
|
|
|
TS_ASSERT(was_in_set == (user_data != 0));
|
|
|
|
if(user_data)
|
2006-06-08 00:15:29 +02:00
|
|
|
TS_ASSERT_EQUALS(*(uintptr_t*)user_data, ~key);
|
2006-05-31 06:17:45 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TA_INSERT:
|
|
|
|
{
|
|
|
|
int was_inserted;
|
|
|
|
|
2006-06-08 21:03:43 +02:00
|
|
|
user_data = lfl_insert(&this_->list, key, sizeof(uintptr_t), &was_inserted);
|
2006-05-31 06:17:45 +02:00
|
|
|
TS_ASSERT(user_data != 0); // only triggers if out of memory
|
|
|
|
*(uintptr_t*)user_data = ~key; // checked above
|
|
|
|
TS_ASSERT(was_in_set == !was_inserted);
|
|
|
|
|
2006-06-08 21:03:43 +02:00
|
|
|
user_data = lfh_insert(&this_->hash, key, sizeof(uintptr_t), &was_inserted);
|
2006-05-31 06:17:45 +02:00
|
|
|
TS_ASSERT(user_data != 0); // only triggers if out of memory
|
|
|
|
*(uintptr_t*)user_data = ~key; // checked above
|
|
|
|
TS_ASSERT(was_in_set == !was_inserted);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TA_ERASE:
|
|
|
|
{
|
|
|
|
int err;
|
|
|
|
|
2006-06-08 21:03:43 +02:00
|
|
|
err = lfl_erase(&this_->list, key);
|
2006-09-22 15:19:40 +02:00
|
|
|
TS_ASSERT(was_in_set == (err == INFO::OK));
|
2006-05-31 06:17:45 +02:00
|
|
|
|
2006-06-08 21:03:43 +02:00
|
|
|
err = lfh_erase(&this_->hash, key);
|
2006-09-22 15:19:40 +02:00
|
|
|
TS_ASSERT(was_in_set == (err == INFO::OK));
|
2006-05-31 06:17:45 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TA_SLEEP:
|
2008-05-12 20:15:08 +02:00
|
|
|
usleep(useconds_t(sleep_duration_ms*1000));
|
2006-05-31 06:17:45 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
TS_FAIL(L"invalid TA_* action");
|
|
|
|
break;
|
|
|
|
} // switch
|
|
|
|
} // while !is_complete
|
|
|
|
|
2007-05-03 17:42:43 +02:00
|
|
|
cpu_AtomicAdd(&this_->num_active_threads, -1);
|
2006-06-08 21:03:43 +02:00
|
|
|
TS_ASSERT(this_->num_active_threads >= 0);
|
|
|
|
|
|
|
|
delete param;
|
2006-05-31 06:17:45 +02:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
TestMultithread()
|
|
|
|
: is_complete(false), num_active_threads(0),
|
2006-11-12 05:02:36 +01:00
|
|
|
list(), hash()
|
|
|
|
{
|
|
|
|
pthread_mutex_init(&mutex, NULL);
|
|
|
|
}
|
2006-05-31 06:17:45 +02:00
|
|
|
|
2006-06-08 21:03:43 +02:00
|
|
|
void disabled_due_to_failure_on_p4_test_multithread()
|
2006-05-31 06:17:45 +02:00
|
|
|
{
|
|
|
|
// this test is randomized; we need deterministic results.
|
|
|
|
srand(1);
|
|
|
|
|
|
|
|
static const double TEST_LENGTH = 30.; // [seconds]
|
2008-01-07 21:03:19 +01:00
|
|
|
const double end_time = timer_Time() + TEST_LENGTH;
|
2006-05-31 06:17:45 +02:00
|
|
|
is_complete = false;
|
|
|
|
|
|
|
|
TS_ASSERT_OK(lfl_init(&list));
|
|
|
|
TS_ASSERT_OK(lfh_init(&hash, 128));
|
|
|
|
TS_ASSERT_OK(pthread_mutex_init(&mutex, 0));
|
|
|
|
|
|
|
|
// spin off test threads (many, to force preemption)
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
const size_t NUM_THREADS = 16;
|
2006-05-31 06:17:45 +02:00
|
|
|
for(uintptr_t i = 0; i < NUM_THREADS; i++)
|
2006-06-08 21:03:43 +02:00
|
|
|
{
|
|
|
|
ThreadFuncParam* param = new ThreadFuncParam(this, i);
|
2007-05-26 20:16:13 +02:00
|
|
|
pthread_t thread; // unused, but GCC raises warning if 0 is passed
|
|
|
|
pthread_create(&thread, 0, thread_func, param);
|
2006-06-08 21:03:43 +02:00
|
|
|
}
|
2006-05-31 06:17:45 +02:00
|
|
|
|
|
|
|
// wait until time interval elapsed (if we get that far, all is well).
|
2008-01-07 21:03:19 +01:00
|
|
|
while(timer_Time() < end_time)
|
2006-05-31 06:17:45 +02:00
|
|
|
usleep(10*1000);
|
|
|
|
|
|
|
|
// signal and wait for all threads to complete (poor man's barrier -
|
|
|
|
// those aren't currently implemented in wpthread).
|
|
|
|
is_complete = true;
|
|
|
|
while(num_active_threads > 0)
|
|
|
|
usleep(5*1000);
|
|
|
|
|
|
|
|
lfl_free(&list);
|
|
|
|
lfh_free(&hash);
|
|
|
|
TS_ASSERT_OK(pthread_mutex_destroy(&mutex));
|
|
|
|
}
|
2008-07-17 19:00:00 +02:00
|
|
|
#endif
|
2006-05-31 06:17:45 +02:00
|
|
|
};
|