⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 threading.h

📁 遗传算法的四个源程序和源代码
💻 H
📖 第 1 页 / 共 2 页
字号:

/*! \file Threading.h
    \brief This file contains declaration of classes and types used to abstract operating system specific threads control.
*/

/*
 * 
 * website: http://www.coolsoft-sd.com/
 * contact: support@coolsoft-sd.com
 *
 */

/*
 * Genetic Algorithm Library
 * Copyright (C) 2007-2008 Coolsoft Software Development
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program 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 General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 */

#ifndef __GA_THREADING_H__
#define __GA_THREADING_H__

#include "Platform.h"

#if defined(GAL_PLATFORM_WIN)

	#include <windows.h>

	#if defined(GAL_SYNTAX_MSVC) && !defined(GAL_SYNTAX_INTL)

		#include <intrin.h>

	#endif

#elif defined(GAL_PLATFORM_NIX)

	#include <pthread.h>
	#include <semaphore.h>

	#if defined(GAL_PLATFORM_MACOS)

		#include <stdio.h>
		#include <string.h>

		#include <libkern/OSAtomic.h>
		#include <sys/types.h>
		#include <unistd.h>

	#endif

	#if defined(GAL_PLATFORM_SOL)

		#include <atomic.h>

	#endif

#endif

/// <summary>Contatins classes and types used to abstract operating system specific threads control.</summary>
namespace Threading
{

	#ifdef __GAL_DOCUMENTATION__

		/// <summary>This type defines system specific type for storing threads objects or handles to them.</summary>
		typedef _SYSTEM_OR_COMPILER_SPECIFIC_ SystemThread;

		/// <summary>This type defines system specific type for storing synchronization objects or handles to them.
		/// System specific synchronization is wrapped by <see cref="GaCriticalSection" /> class.</summary>
		typedef _SYSTEM_OR_COMPILER_SPECIFIC_ SysSyncObject;

		/// <summary>This type defines system specific type for storing semaphores objects or handles to them.
		/// Manipulation over semaphores is done by <c>MAKE_SEMAPHORE</c>, <c>FREE_SEMAPHORE</c>, <c>LOCK_SEMAPHORE</c> and 
		/// <c>UNLOCK_SEMAPHORE</c> macros.</summary>
		typedef _SYSTEM_OR_COMPILER_SPECIFIC_ SysSemaphoreObject;

		/// <summary>This type defines system specific type for storing events objects or handles to them.
		/// Manipulation over events is done by <c>MAKE_EVENT</c>, <c>FREE_EVENT</c>, <c>WAIT_FOR_EVENT</c> and 
		/// <c>SIGNAL_EVENT</c> macros.</summary>
		typedef _SYSTEM_OR_COMPILER_SPECIFIC_ SysEventObject;

		/// <summary>This type is used as return value type for functions which are used as threads' entry points.
		/// This type hides system specific types which are used for the purpose. </summary>
		typedef _SYSTEM_OR_COMPILER_SPECIFIC_ ThreadFunctionReturn;

		/// <summary>Variables/objects of this type are used for storing threads' IDs. This type hides system specific
		/// types which are used for the purpose.</summary>
		typedef _SYSTEM_OR_COMPILER_SPECIFIC_ ThreadID;

		/// <summary><c>ATOMIC_INC</c> macro atomically increments <c>VALUE</c> by one and returns new value.</summary>
		/// <param name="VALUE">variable which is incremented.</param>
		#define ATOMIC_INC(VALUE) _SYSTEM_OR_COMPILER_SPECIFIC_

		/// <summary><c>ATOMIC_DEC</c> macro atomically decrements <c>VALUE</c> by one and returns new value.</summary>
		/// <param name="VALUE">variable which is decremented.</param>
		#define ATOMIC_DEC(VALUE) _SYSTEM_OR_COMPILER_SPECIFIC_

		/// <summary><c>SPINLOCK</c> macro defines mechanism of spinlock.</summary>
		/// <param name="LOCK">variable that is useed as lock.</param>
		#define SPINLOCK(LOCK) _SYSTEM_OR_COMPILER_SPECIFIC_

	#endif

	#if defined(GAL_PLATFORM_WIN)

		#if defined(GAL_SYNTAX_MSVC) && !defined(GAL_SYNTAX_INTL)

			#define ATOMIC_INC(VALUE) _InterlockedIncrement( (volatile long*)&VALUE )
			#define ATOMIC_DEC(VALUE) _InterlockedDecrement( (volatile long*)&VALUE )
			#define SPINLOCK(LOCK) while( _InterlockedExchange( (volatile long*)&LOCK, 1 ) )

		#else

			#define ATOMIC_INC(VALUE) InterlockedIncrement( (LONG*)&VALUE )
			#define ATOMIC_DEC(VALUE) InterlockedDecrement( (LONG*)&VALUE )
			#define SPINLOCK(LOCK) while( InterlockedExchange( (LONG*)&LOCK, 1 ) )

		#endif

	#elif defined(GAL_PLATFORM_MACOS)

		#define ATOMIC_INC(VALUE) OSAtomicIncrement32( (int32_t*)&VALUE )
		#define ATOMIC_DEC(VALUE) OSAtomicDecrement32( (int32_t*)&VALUE )
		#define SPINLOCK(LOCK) while( !OSAtomicCompareAndSwap32( 0, 1, (int32_t*)&LOCK ) )

	#elif defined(GAL_PLATFORM_SOL)

		#define ATOMIC_INC(VALUE) atomic_inc_32_nv( (volatile uint32_t*)&VALUE )
		#define ATOMIC_DEC(VALUE) atomic_dec_32_nv( (volatile uint32_t*)&VALUE )
		#define SPINLOCK(LOCK) while( atomic_swap_32( (volatile uint32_t*)&LOCK, 1 ) )

	#elif defined(GAL_PLATFORM_NIX)

		#if defined(GAL_SYNTAX_INTL)

			#define ATOMIC_INC(VALUE) _InterlockedIncrement( (int*)&VALUE )
			#define ATOMIC_DEC(VALUE) _InterlockedDecrement( (int*)&VALUE )
			#define SPINLOCK(LOCK) while( _InterlockedExchange( (int*)&LOCK, 1 ) )

		#else

			#define ATOMIC_INC(VALUE) __sync_add_and_fetch( (long volatile*)&VALUE, 1L )
			#define ATOMIC_DEC(VALUE) __sync_sub_and_fetch( (long volatile*)&VALUE, 1L )
			#define SPINLOCK(LOCK) while( !__sync_val_compare_and_swap( (long volatile*)&LOCK, 0, 1 ) )

		#endif
	
	#endif


	#if defined(GAL_PLATFORM_WIN)
	
		typedef HANDLE SystemThread;
		typedef DWORD ThreadID;
		typedef int ThreadFunctionReturn;

		typedef CRITICAL_SECTION SysSyncObject;
		typedef HANDLE SysSemaphoreObject;
		typedef HANDLE SysEventObject;

	#elif defined(GAL_PLATFORM_NIX)
	
		typedef pthread_t SystemThread;
		typedef pthread_t ThreadID;

		typedef void* ThreadFunctionReturn;

		typedef pthread_mutex_t SysSyncObject;

		#if defined(GAL_PLATFORM_MACOS)

			typedef sem_t* SysSemaphoreObject;
			typedef sem_t* SysEventObject;

		#else

			typedef sem_t SysSemaphoreObject;
			typedef sem_t SysEventObject;

		#endif
	
	#endif

	/// <summary>This function is used to create operating system object for semaphore and to initialize it.</summary>
	/// <param name="semaphoreHandle">variable which will store handle to newly created semaphore.</param>
	/// <param name="maxCount">maximum count of semaphore, value must be greater then 0. On *nix systems this parameter is ignored.</param>
	/// <param name="initialCount">initial count of semaphore, value must be greater or equals to the 0 and less then or equals to <c>maxCount</c>.</param>
	/// <return>Returns <c>true</c> if the semaphore is successfully created.</returns>
	inline bool MakeSemaphore(SysSemaphoreObject& semaphoreHandle, int maxCount, int initialCount)
	{
		#if defined(GAL_PLATFORM_WIN)

		return ( semaphoreHandle = CreateSemaphore( NULL, initialCount, maxCount, NULL ) ) != NULL;

		#elif defined(GAL_PLATFORM_MACOS)

		static int sem_counter = 0;
		char sem_name[ 40 ];
		strcpy( sem_name, "/tmp/gal_sem" );
		sprintf( sem_name + 12, "_%d", getpid() );
		sprintf( sem_name + strlen( sem_name ), "_%d", ATOMIC_INC( sem_counter ) );

		return ( semaphoreHandle = sem_open( sem_name, O_CREAT, 0644, initialCount ) ) != (sem_t*)SEM_FAILED;

		#elif defined(GAL_PLATFORM_NIX)

		return sem_init( &semaphoreHandle, 0, initialCount ) == 0;

		#endif
	}

	/// <summary>This function is used to free operating system semaphore.</summary>
	/// <param name="semaphoreHandle">reference to variable that holds reference to semaphore.</param>
	/// <return>Returns <c>true</c> if the semaphore is successfully freed.</returns>
	inline bool DeleteSemaphore(SysSemaphoreObject& semaphoreHandle)
	{
		#if defined(GAL_PLATFORM_WIN)

		return CloseHandle( semaphoreHandle ) == S_OK;

		#elif defined(GAL_PLATFORM_MACOS)

		return sem_destroy( semaphoreHandle ) == 0;

		#elif defined(GAL_PLATFORM_NIX)

		return sem_destroy( &semaphoreHandle ) == 0;
		
		#endif
	}

	/// <summary>This function is used to acquire access to critical section protected by semaphore.</summary>
	/// <param name="semaphoreHandle">reference to variable that holds reference to semaphore.</param>
	/// <return>Returns <c>true</c> if the semaphore is successfully acquired.</returns>
	inline bool LockSemaphore(SysSemaphoreObject& semaphoreHandle)
	{
		#if defined(GAL_PLATFORM_WIN)

		return WaitForSingleObject( semaphoreHandle, INFINITE ) != WAIT_FAILED;

		#elif defined(GAL_PLATFORM_MACOS)

		return sem_wait( semaphoreHandle ) == 0;

		#elif defined(GAL_PLATFORM_NIX)

		return sem_wait( &semaphoreHandle ) == 0;

		#endif
	}

	/// <summary>This function is used to release access to critical section protected by semaphore.</summary>
	/// <param name="semaphoreHandle">reference to variable that holds reference to semaphore.</param>
	/// <param name="count">amount by which semaphore's count is increased, value must be grater then 0 and sum
	/// of the value and current semaphore's count must be less then or equals to maximal count of semaphore.</param>
	/// <return>Returns <c>true</c> if the semaphore is successfully released.</returns>
	inline bool UnlockSemaphore(SysSemaphoreObject& semaphoreHandle, int count)
	{
		#if defined(GAL_PLATFORM_WIN)
		
		return ReleaseSemaphore( semaphoreHandle, count, NULL ) != FALSE;

		#elif defined(GAL_PLATFORM_MACOS)

		for( ; count > 0; count-- )
		{
			if( sem_post( semaphoreHandle ) != 0 )
				return false;
		}

		return true;

		#elif defined(GAL_PLATFORM_NIX)

		for( ; count > 0; count-- )
		{
			if( sem_post( &semaphoreHandle ) != 0 )
				return false;
		}

		return true;
		
		#endif
	}

	/// <summary>This function is used to create operating system object for event and to initialize it.</summary>
	/// <param name="eventHandle">reference to variable which will store handle to newly created event.</param>
	/// <param name="intialState">initial state of event. Should be to <c>true</c> if event should be in signaled
	/// state after it is created, otherwise it should be set to <c>false</c>.</param>
	/// <return>Returns <c>true</c> if the event is successfully created.</returns>
	inline bool MakeEvent(SysEventObject& eventHandle, bool intialState)
	{
		#if defined(GAL_PLATFORM_WIN)

		return ( eventHandle = CreateEvent( NULL, FALSE, intialState, NULL ) ) != NULL;

		#elif defined(GAL_PLATFORM_NIX)

		return MakeSemaphore( eventHandle, 1, intialState ? 1 : 0 );

		#endif
	}

	/// <summary>This function is used to free operating system semaphore.</summary>
	/// <param name="eventHandle">reference to variable that holds reference to event.</param>
	/// <return>Returns <c>true</c> if the event is successfully freed.</returns>
	inline bool DeleteEvent(SysEventObject& eventHandle)
	{
		#if defined(GAL_PLATFORM_WIN)

		return CloseHandle( eventHandle ) == S_OK;

		#elif defined(GAL_PLATFORM_NIX)

		return DeleteSemaphore( (SysSemaphoreObject&)eventHandle );

		#endif
	}

	/// <summary>This function is used to block calling thread until event reaches signaled state.
	/// When calling thread is released, event is restared to non-signaled state.</summary>
	/// <param name="eventHandle">reference to variable that holds reference to event.</param>
	/// <return>Returns <c>true</c> if the thread successfully received signal.</returns>
	inline bool WaitForEvent(SysEventObject& eventHandle)
	{
		#if defined(GAL_PLATFORM_WIN)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -