155 lines
3.5 KiB
C++
155 lines
3.5 KiB
C++
// Filename: test_delete.cxx
|
|
// Created by: drose (18Apr06)
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// PANDA 3D SOFTWARE
|
|
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
|
//
|
|
// All use of this software is subject to the terms of the revised BSD
|
|
// license. You should have received a copy of this license along
|
|
// with this source code in a file named "LICENSE."
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
#include "pandabase.h"
|
|
#include "thread.h"
|
|
#include "pmutex.h"
|
|
#include "mutexHolder.h"
|
|
#include "deletedChain.h"
|
|
|
|
// This is the number of passes to make per thread.
|
|
static const int num_passes = 100;
|
|
|
|
// This is the number of doobers to allocate in each pass.
|
|
static const int num_doobers_per_pass = 1000000;
|
|
|
|
// This is the max number to allocate in each chunk.
|
|
static const int max_doobers_per_chunk = 1000;
|
|
|
|
// The number of threads to spawn.
|
|
static const int number_of_threads = 4;
|
|
|
|
#if defined(WIN32_VC) || defined(WIN64_VC)
|
|
static int last_rand = 0;
|
|
#endif /* __WIN32__ */
|
|
|
|
Mutex rand_mutex;
|
|
|
|
static double
|
|
random_f(double max) {
|
|
MutexHolder l(rand_mutex);
|
|
int i = rand();
|
|
#if defined(WIN32_VC) || defined(WIN64_VC)
|
|
last_rand = i;
|
|
#endif /* __WIN32__ */
|
|
return max * (double)i / (double)RAND_MAX;
|
|
}
|
|
|
|
#define OUTPUT(stuff) { \
|
|
MutexHolder holder(Mutex::_notify_mutex); \
|
|
stuff; \
|
|
}
|
|
|
|
class Doober {
|
|
public:
|
|
Doober(int counter) : _counter(counter) {
|
|
}
|
|
~Doober() {
|
|
nassertv(_counter != -1);
|
|
_counter = -1;
|
|
}
|
|
ALLOC_DELETED_CHAIN(Doober);
|
|
|
|
int _counter;
|
|
|
|
public:
|
|
static TypeHandle get_class_type() {
|
|
return _type_handle;
|
|
}
|
|
static void init_type() {
|
|
register_type(_type_handle, "Doober");
|
|
}
|
|
|
|
private:
|
|
static TypeHandle _type_handle;
|
|
};
|
|
typedef pvector<Doober *> Doobers;
|
|
|
|
TypeHandle Doober::_type_handle;
|
|
|
|
|
|
class MyThread : public Thread {
|
|
public:
|
|
MyThread(const string &name) : Thread(name, name)
|
|
{
|
|
}
|
|
|
|
virtual void
|
|
thread_main() {
|
|
OUTPUT(nout << *this << " beginning.\n");
|
|
|
|
#if defined(WIN32_VC) || defined(WIN64_VC)
|
|
rand_mutex.acquire();
|
|
srand(last_rand);
|
|
rand_mutex.release();
|
|
random_f(1.0);
|
|
#endif /* __WIN32__ */
|
|
|
|
Doobers doobers;
|
|
|
|
for (int i = 0; i < num_passes; ++i) {
|
|
int counter = 0;
|
|
|
|
while (counter < num_doobers_per_pass) {
|
|
int num_alloc = (int)random_f(max_doobers_per_chunk);
|
|
for (int i = 0; i < num_alloc; ++i) {
|
|
doobers.push_back(new Doober(++counter));
|
|
}
|
|
int num_del = (int)random_f(max_doobers_per_chunk);
|
|
num_del = min(num_del, (int)doobers.size());
|
|
|
|
for (int j = 0; j < num_del; ++j) {
|
|
assert(!doobers.empty());
|
|
delete doobers.back();
|
|
doobers.pop_back();
|
|
}
|
|
}
|
|
OUTPUT(nout << get_name() << " has " << doobers.size() << " doobers.\n");
|
|
}
|
|
|
|
OUTPUT(nout << *this << " ending.\n");
|
|
}
|
|
|
|
};
|
|
|
|
int
|
|
main(int argc, char *argv[]) {
|
|
Doober::init_type();
|
|
|
|
OUTPUT(nout << "Making " << number_of_threads << " threads.\n");
|
|
|
|
typedef pvector< PT(MyThread) > Threads;
|
|
Threads threads;
|
|
|
|
PT(MyThread) thread = new MyThread("a");
|
|
threads.push_back(thread);
|
|
thread->start(TP_normal, true);
|
|
|
|
for (int i = 1; i < number_of_threads; ++i) {
|
|
char name = 'a' + i;
|
|
PT(MyThread) thread = new MyThread(string(1, name));
|
|
threads.push_back(thread);
|
|
thread->start(TP_normal, true);
|
|
}
|
|
|
|
// Now join all the threads.
|
|
Threads::iterator ti;
|
|
for (ti = threads.begin(); ti != threads.end(); ++ti) {
|
|
(*ti)->join();
|
|
}
|
|
|
|
Thread::prepare_for_exit();
|
|
return (0);
|
|
}
|