//------------------------------------------------------------------------------
// Lamp : Open source game middleware
// Copyright (C) 2004  Junpei Ohtani ( Email : junpee@users.sourceforge.jp )
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//------------------------------------------------------------------------------

/** @file
 * スレッドテスト実装
 * @author Junpee
 */

#include "Test/stdafx.h"
#include "Core/Thread/ThreadTest.h"
#include "Core/Thread/SynchronizedBlock.h"

volatile int ThreadTest::TestThread::count_ = 0;

//------------------------------------------------------------------------------
// コンストラクタ
ThreadTest::ThreadTest(String name) : TestCase(name){
}
//------------------------------------------------------------------------------
// テストスィートの取得
Test* ThreadTest::suite(){
	TestSuite* suite = new TestSuite("ThreadTest");
//	suite->addTest(new TestCaller(ThreadTest, testThread));
//	suite->addTest(new TestCaller(ThreadTest, testRunnable));
	return suite;
}
//------------------------------------------------------------------------------
// スレッドテスト
void ThreadTest::testThread(){
	TestEquals(48, (int)sizeof(Thread));
	const int threadCount = threadCount_;
	Thread* threads[threadCount];
	TestThread::count_ = 0;
	for(int i = 0; i < threadCount; i++){
		threads[i] = new TestThread();
		threads[i]->start();
	}
	for(int i = 0; i < threadCount; i++){
		threads[i]->stop();
		delete threads[i];
	}
	TestEquals(0, TestThread::count_);
}
//------------------------------------------------------------------------------
// 実行可能テスト
void ThreadTest::testRunnable(){
	count_ = 0;
	const int threadCount = threadCount_;
	Thread* threads[threadCount];
	for(int i = 0; i < threadCount; i++){
		threads[i] = new Thread(this);
		threads[i]->start();
		{
			SynchronizedBlock synchronizedBlock(this);
			wait(threads[i]);
		}
	}
	{
		SynchronizedBlock synchronizedBlock(this);
		notifyAll();
	}
	for(int i = 0; i < threadCount; i++){
		threads[i]->stop();
		delete threads[i];
	}
	TestEquals(0, count_);
}
//------------------------------------------------------------------------------
// 実行
void ThreadTest::run(Thread* thread){
	for(int i = 0; i < 1024; i++){
		count_ += i;
		Thread::yield();
		count_ -= i;
		Thread::yield();
	}
}
//------------------------------------------------------------------------------
/// 実行
void ThreadTest::TestThread::run(Thread* thread){
	for(int i = 0; i < 1024; i++){
		count_++;
		Thread::yield();
		count_--;
	}
}
//------------------------------------------------------------------------------
