< prev index next >
src/share/vm/gc/shared/workgroup.cpp
Print this page
*** 252,264 ****
}
WorkGang::WorkGang(const char* name,
uint workers,
bool are_GC_task_threads,
! bool are_ConcurrentGC_threads) :
AbstractWorkGang(name, workers, are_GC_task_threads, are_ConcurrentGC_threads),
! _dispatcher(create_dispatcher(workers))
{ }
AbstractGangWorker* WorkGang::allocate_worker(uint worker_id) {
return new GangWorker(this, worker_id);
}
--- 252,265 ----
}
WorkGang::WorkGang(const char* name,
uint workers,
bool are_GC_task_threads,
! bool are_ConcurrentGC_threads,
! GangTaskDispatcher* dispatcher) :
AbstractWorkGang(name, workers, are_GC_task_threads, are_ConcurrentGC_threads),
! _dispatcher(dispatcher != NULL ? dispatcher: create_dispatcher(workers))
{ }
AbstractGangWorker* WorkGang::allocate_worker(uint worker_id) {
return new GangWorker(this, worker_id);
}
*** 621,625 ****
--- 622,699 ----
#endif
if (_waiters > 0)
// Notify all would be safer, but this is OK, right?
_mon->notify_all();
}
+
+ /////////////// Unit tests ///////////////
+
+ #ifndef PRODUCT
+
+ class CountTask : public AbstractGangTask {
+ volatile jint _count;
+ bool _sleep;
+ public:
+ CountTask(bool sleep) : AbstractGangTask("CountTask"), _sleep(sleep), _count(0) {}
+ virtual void work(uint worker_id) {
+ if (_sleep) {
+ // Sleep a while, to delay the task to allow the coordinator to run.
+ os::sleep(Thread::current(), 100, false);
+ }
+
+ // Count number of times executed.
+ Atomic::inc(&_count);
+ }
+ uint count() { return _count; }
+ };
+
+
+ static void test_workgang_dispatch(bool use_semaphore,
+ uint total_workers,
+ uint active_workers,
+ bool sleep) {
+
+ GangTaskDispatcher* dispatcher = use_semaphore
+ ? (GangTaskDispatcher*) new SemGangTaskDispatcher(total_workers)
+ : (GangTaskDispatcher*) new MutexGangTaskDispatcher();
+
+ // Intentionally leaking WorkGang, since there's no support to delete WorkGangs.
+ WorkGang* gang = new WorkGang("Test WorkGang", total_workers, false, false, dispatcher);
+ gang->initialize_workers();
+
+ gang->set_active_workers(active_workers);
+
+ CountTask task(sleep);
+
+ gang->run_task(&task);
+
+ uint task_count = task.count();
+
+ assert(task_count == active_workers, err_msg("Expected count: %u got: %u", active_workers, task_count));
+ }
+
+ static void test_workgang_dispatch(bool use_semaphore) {
+ const bool sleep = true;
+ const uint total_workers = 8;
+ for (uint active_workers = 1; active_workers <= 4; active_workers++) {
+ test_workgang_dispatch(use_semaphore, total_workers, active_workers, sleep);
+ test_workgang_dispatch(use_semaphore, total_workers, active_workers, !sleep);
+ }
+ }
+
+ static void test_workgang_dispatch_mutex() {
+ test_workgang_dispatch(false);
+ }
+
+ static void test_workgang_dispatch_semaphore() {
+ test_workgang_dispatch(true);
+ }
+
+ void test_workgang() {
+ // Needed to use dynamic number of active workers.
+ FlagSetting fs(UseDynamicNumberOfGCThreads, true);
+
+ test_workgang_dispatch_semaphore();
+ test_workgang_dispatch_mutex();
+ }
+
+ #endif // PRODUCT
< prev index next >