sl@0: /* sl@0: * Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: * All rights reserved. sl@0: * This component and the accompanying materials are made available sl@0: * under the terms of "Eclipse Public License v1.0" sl@0: * which accompanies this distribution, and is available sl@0: * at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: * sl@0: * Initial Contributors: sl@0: * Nokia Corporation - initial contribution. sl@0: * sl@0: * Contributors: sl@0: * sl@0: * Description: sl@0: * Name : threadglobals.h sl@0: * Part of : PThread library sl@0: * Data structures needed for ptherad library sl@0: * Version: sl@0: * sl@0: */ sl@0: sl@0: sl@0: sl@0: #ifndef THREADGLOBALS_H sl@0: #define THREADGLOBALS_H sl@0: sl@0: #include <pthread.h> sl@0: #include <e32std.h> sl@0: #include <limits.h> sl@0: #include "sysif.h" sl@0: sl@0: #include <e32debug.h> sl@0: sl@0: //the semaphore structure sl@0: struct _sem_t sl@0: { sl@0: enum sem_state sl@0: { sl@0: EInitialized, sl@0: EDestroyed, sl@0: EInvalid, sl@0: }; sl@0: sem_state iState; sl@0: int iCount; //iCount and iMutex pair needed sl@0: //because of need for implementing trywait sl@0: RMutex iMutex; sl@0: RSemaphore iSemaphore; sl@0: /******************************************************************* sl@0: Overloading new and delete operators so that they will sl@0: allocate and deallocare memory from/to the private heap of backend sl@0: ********************************************************************/ sl@0: inline TAny* operator new(TUint aSize, TAny* aBase) __NO_THROW sl@0: { sl@0: Mem::FillZ(aBase, aSize); return aBase; sl@0: } sl@0: sl@0: inline TAny* operator new(TUint aSize) __NO_THROW sl@0: { sl@0: return Backend()->Alloc(aSize); sl@0: } sl@0: sl@0: inline TAny* operator new(TUint aSize, TLeave) sl@0: { sl@0: TAny* ptr = Backend()->Alloc(aSize); sl@0: if (ptr == NULL) sl@0: { sl@0: User::Leave(KErrNoMemory); sl@0: } sl@0: return ptr; sl@0: } sl@0: sl@0: inline TAny* operator new(TUint aSize, TUint aExtraSize) __NO_THROW sl@0: { sl@0: return Backend()->Alloc(aSize + aExtraSize); sl@0: } sl@0: sl@0: inline TAny* operator new(TUint aSize, TLeave, TUint aExtraSize) sl@0: { sl@0: TAny* ptr = Backend()->Alloc(aSize + aExtraSize); sl@0: if (ptr == NULL) sl@0: { sl@0: User::Leave(KErrNoMemory); sl@0: } sl@0: return ptr; sl@0: } sl@0: sl@0: inline void operator delete(TAny *aPtr) __NO_THROW sl@0: { sl@0: Backend()->Free( aPtr ); sl@0: } sl@0: }; sl@0: sl@0: typedef struct _sem_node sl@0: { sl@0: struct _sem_node *next; sl@0: _sem_t *sem; sl@0: /******************************************************************* sl@0: Overloading new and delete operators so that they will sl@0: allocate and deallocare memory from/to the private heap of backend sl@0: ********************************************************************/ sl@0: inline TAny* operator new(TUint aSize, TAny* aBase) __NO_THROW sl@0: { sl@0: Mem::FillZ(aBase, aSize); return aBase; sl@0: } sl@0: sl@0: inline TAny* operator new(TUint aSize) __NO_THROW sl@0: { sl@0: return Backend()->Alloc(aSize); sl@0: } sl@0: sl@0: inline TAny* operator new(TUint aSize, TLeave) sl@0: { sl@0: TAny* ptr = Backend()->Alloc(aSize); sl@0: if (ptr == NULL) sl@0: { sl@0: User::Leave(KErrNoMemory); sl@0: } sl@0: return ptr; sl@0: } sl@0: sl@0: inline TAny* operator new(TUint aSize, TUint aExtraSize) __NO_THROW sl@0: { sl@0: return Backend()->Alloc(aSize + aExtraSize); sl@0: } sl@0: sl@0: inline TAny* operator new(TUint aSize, TLeave, TUint aExtraSize) sl@0: { sl@0: TAny* ptr = Backend()->Alloc(aSize + aExtraSize); sl@0: if (ptr == NULL) sl@0: { sl@0: User::Leave(KErrNoMemory); sl@0: } sl@0: return ptr; sl@0: } sl@0: sl@0: inline void operator delete(TAny *aPtr) __NO_THROW sl@0: { sl@0: Backend()->Free( aPtr ); sl@0: } sl@0: }_sem_node_t; sl@0: sl@0: sl@0: // Thread default attributes sl@0: #define DEFAULT_STACK_SIZE 0x2000 sl@0: #define DEFAULT_DETACH_STATE PTHREAD_CREATE_JOINABLE sl@0: sl@0: #define THR_DISABLE_PTHREAD_TRACE 1 sl@0: sl@0: #define DEFAULT_THREAD_PRIORITY 100 sl@0: sl@0: #ifdef THR_DISABLE_PTHREAD_TRACE sl@0: sl@0: #define THR_PRINTF(string) \ sl@0: {\ sl@0: } sl@0: sl@0: #else //THR_DISABLE_PTHREAD_TRACE sl@0: sl@0: #define THR_PRINTF(string) \ sl@0: {\ sl@0: #ifdef _DEBUG \ sl@0: RDebug::Printf(string);\ sl@0: #endif \ //_DEBUG sl@0: } sl@0: sl@0: #endif //THR_DISABLE_PTHREAD_TRACE sl@0: sl@0: #define THR_NULL_ASSERT(x,val,format) \ sl@0: { \ sl@0: if ( (x) == NULL ) \ sl@0: { \ sl@0: THR_PRINTF(format); \ sl@0: return ((void*)0); \ sl@0: } \ sl@0: } sl@0: sl@0: #define STAT_FLAG_SIZE (PTHREAD_KEYS_MAX / 32) sl@0: sl@0: /* thread state. */ sl@0: enum sl@0: { sl@0: _THREAD_RUNNING, sl@0: _THREAD_ZOMBIE sl@0: }; sl@0: sl@0: /* Key status */ sl@0: enum sl@0: { sl@0: _KEY_UNUSED, sl@0: _KEY_USED sl@0: }; sl@0: sl@0: /* MainFlag */ sl@0: enum sl@0: { sl@0: _MAIN_THREAD=0, sl@0: _NON_MAIN_THREAD sl@0: }; sl@0: sl@0: typedef struct sl@0: { sl@0: destructor_routine destr; sl@0: }_pthread_key_node; sl@0: sl@0: // TLS Keys link list node sl@0: typedef struct _pkey_node sl@0: { sl@0: int keyNumber; sl@0: struct _pkey_node *next; sl@0: void *tls; sl@0: /******************************************************************* sl@0: Overloading new and delete operators so that they will sl@0: allocate and deallocare memory from/to the private heap of backend sl@0: ********************************************************************/ sl@0: inline TAny* operator new(TUint aSize, TAny* aBase) __NO_THROW sl@0: { sl@0: Mem::FillZ(aBase, aSize); return aBase; sl@0: } sl@0: sl@0: inline TAny* operator new(TUint aSize) __NO_THROW sl@0: { sl@0: return Backend()->Alloc(aSize); sl@0: } sl@0: sl@0: inline TAny* operator new(TUint aSize, TLeave) sl@0: { sl@0: TAny* ptr = Backend()->Alloc(aSize); sl@0: if (ptr == NULL) sl@0: { sl@0: User::Leave(KErrNoMemory); sl@0: } sl@0: return ptr; sl@0: } sl@0: sl@0: inline TAny* operator new(TUint aSize, TUint aExtraSize) __NO_THROW sl@0: { sl@0: return Backend()->Alloc(aSize + aExtraSize); sl@0: } sl@0: sl@0: inline TAny* operator new(TUint aSize, TLeave, TUint aExtraSize) sl@0: { sl@0: TAny* ptr = Backend()->Alloc(aSize + aExtraSize); sl@0: if (ptr == NULL) sl@0: { sl@0: User::Leave(KErrNoMemory); sl@0: } sl@0: return ptr; sl@0: } sl@0: sl@0: inline void operator delete(TAny *aPtr) __NO_THROW sl@0: { sl@0: Backend()->Free( aPtr ); sl@0: } sl@0: }_pkey_node_t; sl@0: sl@0: typedef struct _pthread_node _pthread_node_t; sl@0: #ifdef __X86GCC__ sl@0: // MinGW GCC compiler does not like typedef struct definitions with no tag sl@0: typedef struct _global_data_tag sl@0: #else sl@0: typedef struct _global_data_t sl@0: #endif //__X86GCC__ sl@0: { sl@0: _pthread_node_t *start; sl@0: unsigned int threadCount; sl@0: RMutex lockThreadTable; sl@0: RMutex globalLockForMutex; sl@0: // TLS Keys sl@0: _pthread_key_node pthread_key_list[PTHREAD_KEYS_MAX]; sl@0: unsigned int statusflag[STAT_FLAG_SIZE]; sl@0: // Semaphore list sl@0: _sem_node_t *semStart; sl@0: RMutex lockSemTable; sl@0: /******************************************************************* sl@0: Overloading new and delete operators so that they will sl@0: allocate and deallocare memory from/to the private heap of backend sl@0: ********************************************************************/ sl@0: sl@0: inline TAny* operator new(TUint aSize, TAny* aBase) __NO_THROW sl@0: { sl@0: Mem::FillZ(aBase, aSize); return aBase; sl@0: } sl@0: sl@0: inline TAny* operator new(TUint aSize) __NO_THROW sl@0: { sl@0: return Backend()->Alloc(aSize); sl@0: } sl@0: sl@0: inline TAny* operator new(TUint aSize, TLeave) sl@0: { sl@0: TAny* ptr = Backend()->Alloc(aSize); sl@0: if (ptr == NULL) sl@0: { sl@0: User::Leave(KErrNoMemory); sl@0: } sl@0: return ptr; sl@0: } sl@0: sl@0: inline TAny* operator new(TUint aSize, TUint aExtraSize) __NO_THROW sl@0: { sl@0: return Backend()->Alloc(aSize + aExtraSize); sl@0: } sl@0: sl@0: inline TAny* operator new(TUint aSize, TLeave, TUint aExtraSize) sl@0: { sl@0: TAny* ptr = Backend()->Alloc(aSize + aExtraSize); sl@0: if (ptr == NULL) sl@0: { sl@0: User::Leave(KErrNoMemory); sl@0: } sl@0: return ptr; sl@0: } sl@0: sl@0: inline void operator delete(TAny *aPtr) __NO_THROW sl@0: { sl@0: Backend()->Free( aPtr ); sl@0: } sl@0: sl@0: inline void operator delete(TAny *aPtr, TLeave) sl@0: { sl@0: Backend()->Free( aPtr ); sl@0: return; sl@0: } sl@0: sl@0: inline void operator delete(TAny *aPtr, TAny* aBase) __NO_THROW sl@0: { sl@0: aBase = aBase; sl@0: Backend()->Free( aPtr ); sl@0: return; sl@0: } sl@0: sl@0: inline void operator delete(TAny *aPtr, TUint aExtraSize) __NO_THROW sl@0: { sl@0: aExtraSize = aExtraSize; sl@0: Backend()->Free( aPtr ); sl@0: return; sl@0: } sl@0: sl@0: inline void operator delete(TAny *aPtr, TLeave, TUint aExtraSize) sl@0: { sl@0: aExtraSize = aExtraSize; sl@0: Backend()->Free( aPtr ); sl@0: return; sl@0: } sl@0: sl@0: _global_data_t(); sl@0: ~_global_data_t(); sl@0: sl@0: }_global_data_t; sl@0: sl@0: sl@0: _global_data_t* GetGlobals(); sl@0: #define glbHeadNode GetGlobals() sl@0: sl@0: typedef struct _pthread_node sl@0: { sl@0: struct _pthread_node *next; sl@0: RMutex lockNode; sl@0: _global_data_t *glbDataPtr; sl@0: unsigned int detachState; sl@0: unsigned int threadState; sl@0: void *returnValue; sl@0: TBool hasAnyThreadJoined; sl@0: RThread rtHandle; sl@0: unsigned int threadId; sl@0: // void *tls[PTHREAD_KEYS_MAX]; sl@0: _pkey_node_t *tlsHead; sl@0: int priority; sl@0: int mainFlag; sl@0: void *cleanStackPtr; sl@0: /******************************************************************* sl@0: Overloading new and delete operators so that they will sl@0: allocate and deallocare memory from/to the private heap of backend sl@0: ********************************************************************/ sl@0: inline TAny* operator new(TUint aSize, TAny* aBase) __NO_THROW sl@0: { sl@0: Mem::FillZ(aBase, aSize); return aBase; sl@0: } sl@0: sl@0: inline TAny* operator new(TUint aSize) __NO_THROW sl@0: { sl@0: return Backend()->Alloc(aSize); sl@0: } sl@0: sl@0: inline TAny* operator new(TUint aSize, TLeave) sl@0: { sl@0: TAny* ptr = Backend()->Alloc(aSize); sl@0: if (ptr == NULL) sl@0: { sl@0: User::Leave(KErrNoMemory); sl@0: } sl@0: return ptr; sl@0: } sl@0: sl@0: inline TAny* operator new(TUint aSize, TUint aExtraSize) __NO_THROW sl@0: { sl@0: return Backend()->Alloc(aSize + aExtraSize); sl@0: } sl@0: sl@0: inline TAny* operator new(TUint aSize, TLeave, TUint aExtraSize) sl@0: { sl@0: TAny* ptr = Backend()->Alloc(aSize + aExtraSize); sl@0: if (ptr == NULL) sl@0: { sl@0: User::Leave(KErrNoMemory); sl@0: } sl@0: return ptr; sl@0: } sl@0: sl@0: inline void operator delete(TAny *aPtr) __NO_THROW sl@0: { sl@0: Backend()->Free( aPtr ); sl@0: } sl@0: }_pthread_node_t; sl@0: sl@0: sl@0: sl@0: sl@0: #endif //THREADGLOBALS_H