Пример #1
0
void PoolRelease( MemPool* pPool )
{
  if ( pPool ) {
    bool result = KMutexLock( &pPool->mutex, WAIT_FOREVER );
    if ( result ) {
      KMutexDelete( &pPool->mutex );
      memset( pPool->pBackingStore, 0, pPool->backingBufferSize );
      pPool->pBackingStore = 0;
      pPool->pFreeBits = 0;
    }
    else{
      LOG( "%s(): Unable to lock mutex for release", __FUNCTION__ );
      assert( 0 );
    }
  }
}
Пример #2
0
void PoolFree( MemPool* pPool, void* buf )
{
  if ( pPool && buf ) {
    uint32_t indexToFree = ( uint32_t )( (uint8_t*)buf - (uint8_t*)pPool->pBackingStore );
    if ( indexToFree >= pPool->numOfUnits ) {
      LOG( "%s(): Got out of bounds index to free: %d, ptr: %p (start: %p)", 
           __FUNCTION__, indexToFree, buf, pPool->pBackingStore );
      assert( 0 );
    }
    if ( KMutexLock( &pPool->mutex, WAIT_FOREVER ) ) {
      MarkIndexFree( pPool, indexToFree, 0 );
      KMutexUnlock( &pPool->mutex );
    }
    else
    {
      LOG( "%s(): Couldn't lock mutex", __FUNCTION__ );
      assert( 0 );
    }
  }
}
Пример #3
0
void* PoolAlloc( MemPool* pPool )
{
  void* retval = 0;
  if ( pPool ) {
    if ( KMutexLock( &pPool->mutex, WAIT_FOREVER ) ) {
      uint32_t freeIndex = GetFreeIndex( pPool, 0 );
      if ( freeIndex < pPool->numOfUnits ) {
        uint32_t sizeofUnit = pPool->backingBufferSize / pPool->numOfUnits;
        retval = ( ( uint8_t* )pPool->pBackingStore + ( sizeofUnit * freeIndex ) );
        LOG( "%s(): Retval: %p ( index: %d )", __FUNCTION__, retval, freeIndex );
      }
      KMutexUnlock( &pPool->mutex );
    }
    else
    {
      LOG( "%s(): Couldn't lock mutex", __FUNCTION__ );
      assert( 0 );
    }
  }
  return retval;
}
static void StartThread( void* arg )
{
  KMutex locks[NESTING_DEPTH - 1];
  DonorThreadParams donorParams[ NESTING_DEPTH ];
  TestData* pTestData = ( TestData* ) arg;

  for (uint32_t i = 0; i < NESTING_DEPTH - 1; i++) {
    char tmp[30];
    bool workerMutexCreateResult = false;
    sprintf_s( tmp, sizeof(tmp), "Mutex %d", i );
    workerMutexCreateResult = KMutexCreate( &locks[ i ], tmp );
  }

  KMutexLock( &locks[0], WAIT_FOREVER );
  ConsoleLogLine( "%s got lock, My Priority: %d", s_data.threads[0].threadName,
       KThreadGetPriority( &pTestData->threads[ 0 ] ) );

  for ( uint32_t i = 1; i < NESTING_DEPTH; i++)
  {
    char name[16];
    int thread_priority;
    snprintf (name, sizeof name, "thread %d", i);
    thread_priority = PRI_MIN + i * 3;

    donorParams[ i ].lockPair.first = i < NESTING_DEPTH - 1 ? locks + i : NULL;
    donorParams[ i ].lockPair.second = locks + i - 1;
    donorParams[ i ].i = i;
    donorParams[ i ].pThread = &pTestData->threads[ i ];
    donorParams[ i ].pTestData = pTestData;
    KThreadCreateParams params = {
        .fn = DonorThreadFunction,
        .pStack = pTestData->stacks[ i ],
        .pThreadName = name,
        .stackSizeInBytes = sizeof( pTestData->stacks[ i ] ),
        .threadArg = &donorParams[i],
        .threadPriority = thread_priority
    };
    ConsoleLogLine( "Starting %s with priority: %d", name, thread_priority );
    TEST_ASSERT( KThreadCreate( &pTestData->threads[ i ], &params ) );
    /*
    ConsoleLogLine ("%s should have priority %d.  Actual priority: %d.",
         name, thread_priority, KThreadGetPriority( &pTestData->threads[ i ] ) );
    snprintf (name, sizeof name, "interloper %d", i);
    interloperParams[ i ].i = i;
    interloperParams[ i ].pThread = &pTestData->interloperThreads[ i ];
    interloperParams[ i ].pTestData = pTestData;
    KThreadCreateParams paramsInterloper = {
        .fn = InterloperThreadFunction,
        .pStack = pTestData->interloperStacks[ i ],
        .pThreadName = name,
        .stackSizeInBytes = sizeof( pTestData->interloperStacks[ i ] ),
        .threadArg = &interloperParams[ i ],
        .threadPriority = thread_priority - 1,
    };
    TEST_ASSERT( KThreadCreate( &pTestData->interloperThreads[ i ], &paramsInterloper ) );
     */
  }
  TEST_ASSERT_EQUAL_INT( NESTING_DEPTH - 1, pTestData->currentThreadIndexToRelease );
  KMutexUnlock( &locks[ 0 ] );
  /*
  ConsoleLogLine("%s finishing with priority %d.\n", KThreadGetName( &pTestData->threads[ 0 ] ),
       KThreadGetPriority( &pTestData->threads[ 0 ] ) );
       */
  TEST_ASSERT( KThreadJoin( &pTestData->threads[ 1 ] ) && KThreadJoin( &pTestData->interloperThreads[ 1 ] ) );
}

static void TestPriorityDonateChain( void )
{
  TestData* pTestData = &s_data;
  pTestData->currentThreadIndexToRelease = 0;
  KThreadCreateParams startThread = {
      .fn = StartThread,
      .pStack = pTestData->stacks[ 0 ],
      .pThreadName = "StartThread",
      .stackSizeInBytes = THREAD_STACK_SIZE,
      .threadArg = pTestData,
      .threadPriority = PRI_MIN,
  };
  pTestData->currentThreadIndexToRelease = 0;
  bool startThreadCreateResult = KThreadCreate( &pTestData->threads[ 0 ], &startThread );
  TEST_ASSERT( startThreadCreateResult );
  //Test ends when StartThread Ends
  bool waitForStartThreadEnd = KThreadJoin( &pTestData->threads[ 0 ] );
  TEST_ASSERT( waitForStartThreadEnd );
}

static void
DonorThreadFunction( void *args )
{
  DonorThreadParams* pParams = ( DonorThreadParams* )args;

  if (pParams->lockPair.first)
    KMutexLock(pParams->lockPair.first, WAIT_FOREVER );
  ConsoleLogLine( "%s priority %d, Actual priority: %d\n",
       KThreadGetName( pParams->pThread ), KThreadGetPriority( pParams->pThread ) );
  TEST_ASSERT_EQUAL_INT( pParams->i - 1, pParams->pTestData->currentThreadIndexToRelease );
  pParams->pTestData->currentThreadIndexToRelease = pParams->i;
  KMutexLock(pParams->lockPair.second, WAIT_FOREVER );
  TEST_ASSERT_EQUAL_INT( NESTING_DEPTH - pParams->i, pParams->pTestData->currentThreadIndexToRelease );
  pParams->pTestData->currentThreadIndexToRelease = NESTING_DEPTH - ( pParams->i + 1 );
  KMutexUnlock(pParams->lockPair.second);
  /*
  ConsoleLogLine ("%s should have priority %d. Actual priority: %d\n",
       KThreadGetName( pParams->pThread ), (NESTING_DEPTH - 1) * 3,
       KThreadGetPriority( pParams->pThread ) );
       */

  if (pParams->lockPair.first)
    KMutexUnlock(pParams->lockPair.first);

/*
  ConsoleLogLine("%s finishing with priority %d.\n", KThreadGetName( pParams->pThread ),
       KThreadGetPriority( pParams->pThread ) );
       */
}