connectivitylayer/isce/isirouter_dll/src/isithreadcontainer.cpp
changeset 0 63b37f68c1ce
child 9 8486d82aef45
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/connectivitylayer/isce/isirouter_dll/src/isithreadcontainer.cpp	Fri Nov 06 17:28:23 2009 +0000
@@ -0,0 +1,201 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+* 
+* Description: 
+*
+*/
+
+
+
+#include <kernel.h>               // For Kern
+#include "isiroutertrace.h"       // For C_TRACE, ASSERT_RESET.. and fault codes
+#include "isiinternaldefs.h"      // For KAmountOfKernelThreads...
+#include "isithreadcontainer.h"   // For DISIThreadContainer
+
+// Faults
+enum TISIThreadContainerFaults
+    {
+    EISIThreadContainerDfcQAllocFailure = 0x01,
+    EISIThreadContainerDfcQAllocFailure1,
+    EISIThreadContainerUnknownThreadType,
+    EISIThreadContainerNULLThreadPtr,
+    EISIThreadContainerThreadNotFound,
+    EISIThreadContainerOverflow,
+    EISIThreadContainerOverflow1,
+    EISIThreadContainerUnderflow,
+    EISIThreadContainerUnderflow1,
+    };
+
+
+_LIT8( KISIKernelClientThread, "ISIKernelClientThread" );
+_LIT8( KISIUserClientThread, "ISIUserClientThread" );
+
+const TInt KDefaultDfcThreadPriority( 27 );
+const TUint8 KMaxThreadUsers( 255 );
+const TUint8 KMaxThreadNameLength( 25 );
+
+DISIThreadContainer::DISIThreadContainer()
+    {
+    C_TRACE( ( _T( "DISIThreadContainer::DISIThreadContainer>" ) ) );
+    TUint8 nameIndex = 0;
+    for( TUint8 i( 0 ); i < KAmountOfKernelThreads; i++ )
+        {
+        iNameTable[ nameIndex ] = HBuf8::New( KMaxThreadNameLength );
+        iNameTable[ nameIndex ]->Append( (&KISIKernelClientThread)->Ptr(), (&KISIKernelClientThread)->Length() );
+        iNameTable[ nameIndex ]->AppendNum( i, EDecimal );
+        Kern::DfcQCreate( iKClientDfcQueList[ i ], KDefaultDfcThreadPriority, iNameTable[ nameIndex ] );
+        ASSERT_RESET_ALWAYS( iKClientDfcQueList[ i ], ( EISIThreadContainerDfcQAllocFailure | EDISIThreadContainerTraceId << KClassIdentifierShift ) );
+        nameIndex++;
+        }
+    for( TUint8 i( 0 ); i < KAmountOfUserThreads; i++ )
+        {
+        iNameTable[ nameIndex ] = HBuf8::New( KMaxThreadNameLength );
+        iNameTable[ nameIndex ]->Append( (&KISIUserClientThread)->Ptr(), (&KISIUserClientThread)->Length() );
+        iNameTable[ nameIndex ]->AppendNum( i, EDecimal );
+        Kern::DfcQCreate( iUClientDfcQueList[ i ], KDefaultDfcThreadPriority, iNameTable[ nameIndex ] );
+        ASSERT_RESET_ALWAYS( iUClientDfcQueList[ i ], ( EISIThreadContainerDfcQAllocFailure1 | EDISIThreadContainerTraceId << KClassIdentifierShift ) );
+        nameIndex++;
+        }
+    C_TRACE( ( _T( "DISIThreadContainer::DISIThreadContainer<" ) ) );
+    }
+
+DISIThreadContainer::~DISIThreadContainer()
+    {
+    C_TRACE( ( _T( "DISIThreadContainer::~DISIThreadContainer>" ) ) );
+    for( TUint8 i( 0 ); i < ( KAmountOfKernelThreads + KAmountOfUserThreads ); i++ )
+        {
+        if( iNameTable[ i ] )
+            {
+            delete iNameTable[ i ];
+            iNameTable[ i ] = NULL;
+            }
+        }
+    for( TUint8 i( 0 ); i < KAmountOfKernelThreads; i++ )
+        {
+        if( iKClientDfcQueList[ i ] )
+            {
+            delete iKClientDfcQueList[ i ];
+            iKClientDfcQueList[ i ] = NULL;
+            }
+        }
+    for( TUint8 i( 0 ); i < KAmountOfUserThreads; i++ )
+        {
+        if( iUClientDfcQueList[ i ] )
+            {
+            delete iUClientDfcQueList[ i ];
+            iUClientDfcQueList[ i ] = NULL;
+            }
+        }
+    C_TRACE( ( _T( "DISIThreadContainer::~DISIThreadContainer<" ) ) );
+    }
+
+TDfcQue* DISIThreadContainer::AllocateThread( const MISIChannelRouterIf::TISIDfcQThreadType aType )
+    {
+    C_TRACE( ( _T( "DISIThreadContainer::AllocateThread %d>" ), aType ) );
+    TDfcQue* tmpPtr( NULL );
+    switch( aType )
+        {
+        case MISIChannelRouterIf::EISIKernelMainThread:  
+        case MISIChannelRouterIf::EISIKernelRequestCompletionThread:
+            {
+            tmpPtr = ReserveKernelThread();
+            break;
+            }
+        case MISIChannelRouterIf::EISIUserMainThread:
+        case MISIChannelRouterIf::EISIUserRequestCompletionThread:
+            {
+            tmpPtr = ReserveUserThread();
+            break;
+            }
+        default:
+            {
+            ASSERT_RESET_ALWAYS( 0, ( EISIThreadContainerUnknownThreadType | EDISIThreadContainerTraceId << KClassIdentifierShift ) );
+            break;
+            }
+        }
+    ASSERT_RESET_ALWAYS( tmpPtr, ( EISIThreadContainerNULLThreadPtr | EDISIThreadContainerTraceId << KClassIdentifierShift ) );
+    C_TRACE( ( _T( "DISIThreadContainer::AllocateThread %d 0x%x<" ), aType, tmpPtr ) );
+    return tmpPtr;
+    }
+
+TDfcQue* DISIThreadContainer::ReserveKernelThread()
+    {
+    C_TRACE( ( _T( "DISIThreadContainer::ReservekernelThread>" ) ) );
+    TUint8 clientCount = iKThreadOccupation[ 0 ];
+    TUint8 index = 0;
+    for( TUint8 i( 0 ) ; i < KAmountOfKernelThreads; i++ )
+        {
+        if( clientCount > iKThreadOccupation[ i ] )
+            {
+            clientCount = iKThreadOccupation[ i ];
+            index = i;
+            }
+        }
+    ++iKThreadOccupation[ index ];
+    ASSERT_RESET_ALWAYS( iKThreadOccupation[ index ] <= KMaxThreadUsers, ( EISIThreadContainerOverflow | EDISIThreadContainerTraceId << KClassIdentifierShift ) );
+    C_TRACE( ( _T( "DISIThreadContainer::ReserveKernelThread 0x%x %d %d<" ), iKClientDfcQueList[ index ], iKThreadOccupation[ index ], index ) );
+    return iKClientDfcQueList[ index ];
+    }
+
+TDfcQue* DISIThreadContainer::ReserveUserThread()
+    {
+    C_TRACE( ( _T( "DISIThreadContainer::ReserveUserThread>" ) ) );
+    TUint8 clientCount = iUThreadOccupation[ 0 ];
+    TUint8 index = 0;
+    for( TUint8 i( 0 ); i < KAmountOfUserThreads; i++ )
+        {
+        if( clientCount > iUThreadOccupation[ i ] )
+            {
+            clientCount = iUThreadOccupation[ i ];
+            index = i;
+            }
+        }
+    ++iUThreadOccupation[ index ];
+    ASSERT_RESET_ALWAYS( iUThreadOccupation[ index ] <= KMaxThreadUsers, ( EISIThreadContainerOverflow1 | EDISIThreadContainerTraceId << KClassIdentifierShift ) );
+    C_TRACE( ( _T( "DISIThreadContainer::ReserveUserThread 0x%x %d %d<" ), iUClientDfcQueList[ index ], iUThreadOccupation[ index ], index ) );
+    return iUClientDfcQueList[ index ];
+    }
+
+void DISIThreadContainer::DeallocateThread( TDfcQue* aThread )
+    {
+    C_TRACE( ( _T( "DISIThreadContainer::DeallocateThread 0x%x>" ), aThread ) );
+    TBool found( EFalse );
+    for( TUint8 i( 0 ) ; i < KAmountOfKernelThreads; i++ )
+        {
+        if( aThread == iKClientDfcQueList[ i ] )
+            {
+            --iKThreadOccupation[ i ];
+            ASSERT_RESET_ALWAYS( iKThreadOccupation[ i ] != KMaxThreadUsers, ( EISIThreadContainerUnderflow | EDISIThreadContainerTraceId << KClassIdentifierShift ) );
+            C_TRACE( ( _T( "DISIThreadContainer DeallocKThread 0x%x %d %d>" ), aThread, iKThreadOccupation[ i ], i ) );
+            found = ETrue;
+            break;
+            }
+        }
+    if( !found )
+        {
+        for( TUint8 i( 0 ) ; i < KAmountOfUserThreads; i++ )
+            {
+            if( aThread == iUClientDfcQueList[ i ] )
+                {
+                --iUThreadOccupation[ i ];
+                ASSERT_RESET_ALWAYS( iUThreadOccupation[ i ] != KMaxThreadUsers, ( EISIThreadContainerUnderflow1 | EDISIThreadContainerTraceId << KClassIdentifierShift ) );
+                C_TRACE( ( _T( "DISIThreadContainer DeallocUThread 0x%x %d %d>" ), aThread, iUThreadOccupation[ i ], i ) );
+                found = ETrue;
+                break;
+                }
+            }
+        }
+    ASSERT_RESET_ALWAYS( found, ( EISIThreadContainerThreadNotFound | EDISIThreadContainerTraceId << KClassIdentifierShift ) );
+    C_TRACE( ( _T( "DISIThreadContainer::DeallocateThread 0x%x<" ), aThread ) );
+    }
+