📄 threading.h
字号:
/*! \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 + -