mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-19 05:06:25 -04:00
119 lines
3.0 KiB
C++
Executable File
119 lines
3.0 KiB
C++
Executable File
// Filename: test_concurrency.cxx
|
|
// Created by: drose (06Apr06)
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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 "pointerTo.h"
|
|
#include "trueClock.h"
|
|
|
|
// The number of iterations to spin within each thread, before
|
|
// printing output.
|
|
static const long long iterations_per_output = 100000000;
|
|
|
|
// The amount of time, in seconds, to wait between spawning threads.
|
|
static const double delay_between_threads = 2.0;
|
|
|
|
// The amount of time, in seconds, for each thread to run.
|
|
static const double thread_run_time = 15.0;
|
|
|
|
// The number of threads to spawn.
|
|
static const int number_of_threads = 4;
|
|
|
|
// Number of bytes to reserve between writable memory pointers.
|
|
static const int block_size = 64;
|
|
|
|
static Mutex _output_lock;
|
|
|
|
union MemBlock {
|
|
char _pad[block_size];
|
|
int _value;
|
|
};
|
|
|
|
volatile MemBlock memblock[number_of_threads];
|
|
|
|
#define OUTPUT(stuff) { \
|
|
MutexHolder holder(_output_lock); \
|
|
stuff; \
|
|
}
|
|
|
|
class MyThread : public Thread {
|
|
public:
|
|
MyThread(const string &name, int index) :
|
|
Thread(name, name),
|
|
_index(index)
|
|
{
|
|
}
|
|
|
|
virtual void thread_main() {
|
|
OUTPUT(nout << *this << " beginning.\n");
|
|
|
|
double total_seconds = 0.0;
|
|
TrueClock *clock = TrueClock::get_global_ptr();
|
|
volatile int snarf;
|
|
|
|
while (total_seconds < thread_run_time) {
|
|
double start_time = clock->get_short_time();
|
|
|
|
for (long long i = 0; i < iterations_per_output; ++i) {
|
|
memblock[_index]._value = snarf;
|
|
}
|
|
|
|
double end_time = clock->get_short_time();
|
|
|
|
double elapsed_seconds = end_time - start_time;
|
|
double iterations_per_second = iterations_per_output / elapsed_seconds;
|
|
OUTPUT(nout << *this << " achieving "
|
|
<< iterations_per_second / 1000000.0
|
|
<< " million iterations per second.\n");
|
|
|
|
total_seconds += elapsed_seconds;
|
|
}
|
|
|
|
OUTPUT(nout << *this << " exiting.\n");
|
|
}
|
|
|
|
int _index;
|
|
};
|
|
|
|
int
|
|
main(int argc, char *argv[]) {
|
|
OUTPUT(nout << "Making " << number_of_threads << " threads.\n");
|
|
|
|
typedef pvector< PT(MyThread) > Threads;
|
|
Threads threads;
|
|
|
|
PT(MyThread) thread = new MyThread("a", 0);
|
|
threads.push_back(thread);
|
|
thread->start(TP_normal, true);
|
|
|
|
for (int i = 1; i < number_of_threads; ++i) {
|
|
char name = 'a' + i;
|
|
Thread::sleep(delay_between_threads);
|
|
PT(MyThread) thread = new MyThread(string(1, name), i);
|
|
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;
|
|
}
|