Matter SDK Coverage Report
Current view: top level - lib/support - Pool.cpp (source / functions) Coverage Total Hit
Test: SHA:b879ecb8e99e175eea0a293a888bda853da2b19c Lines: 86.4 % 103 89
Test Date: 2025-01-17 19:00:11 Functions: 83.3 % 12 10

            Line data    Source code
       1              : /*
       2              :  *
       3              :  *    Copyright (c) 2020 Project CHIP Authors
       4              :  *    Copyright (c) 2013 Nest Labs, Inc.
       5              :  *    All rights reserved.
       6              :  *
       7              :  *    Licensed under the Apache License, Version 2.0 (the "License");
       8              :  *    you may not use this file except in compliance with the License.
       9              :  *    You may obtain a copy of the License at
      10              :  *
      11              :  *        http://www.apache.org/licenses/LICENSE-2.0
      12              :  *
      13              :  *    Unless required by applicable law or agreed to in writing, software
      14              :  *    distributed under the License is distributed on an "AS IS" BASIS,
      15              :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      16              :  *    See the License for the specific language governing permissions and
      17              :  *    limitations under the License.
      18              :  */
      19              : 
      20              : #include <lib/support/CodeUtils.h>
      21              : #include <lib/support/Pool.h>
      22              : 
      23              : namespace chip {
      24              : 
      25              : #if CHIP_SYSTEM_CONFIG_POOL_USE_HEAP
      26              : 
      27              : bool HeapObjectPoolExitHandling::sIgnoringLeaksOnExit   = false;
      28              : bool HeapObjectPoolExitHandling::sExitHandlerRegistered = false;
      29              : 
      30            0 : void HeapObjectPoolExitHandling::IgnoreLeaksOnExit()
      31              : {
      32            0 :     if (sExitHandlerRegistered)
      33              :     {
      34            0 :         return;
      35              :     }
      36              : 
      37            0 :     int ret = atexit(ExitHandler);
      38            0 :     if (ret != 0)
      39              :     {
      40            0 :         ChipLogError(Controller, "IgnoreLeaksOnExit: atexit failed: %d\n", ret);
      41              :     }
      42            0 :     sExitHandlerRegistered = true;
      43              : }
      44              : 
      45            0 : void HeapObjectPoolExitHandling::ExitHandler()
      46              : {
      47            0 :     sIgnoringLeaksOnExit = true;
      48            0 : }
      49              : 
      50              : #endif // CHIP_SYSTEM_CONFIG_POOL_USE_HEAP
      51              : 
      52              : namespace internal {
      53              : 
      54          156 : StaticAllocatorBitmap::StaticAllocatorBitmap(void * storage, std::atomic<tBitChunkType> * usage, size_t capacity,
      55          156 :                                              size_t elementSize) :
      56              :     StaticAllocatorBase(capacity),
      57          156 :     mElements(storage), mElementSize(elementSize), mUsage(usage)
      58              : {
      59          304 :     for (size_t word = 0; word * kBitChunkSize < Capacity(); ++word)
      60              :     {
      61          148 :         mUsage[word].store(0);
      62              :     }
      63          156 : }
      64              : 
      65          975 : void * StaticAllocatorBitmap::Allocate()
      66              : {
      67         1231 :     for (size_t word = 0; word * kBitChunkSize < Capacity(); ++word)
      68              :     {
      69         1227 :         auto & usage = mUsage[word];
      70         1227 :         auto value   = usage.load(std::memory_order_relaxed);
      71        38823 :         for (size_t offset = 0; offset < kBitChunkSize && offset + word * kBitChunkSize < Capacity(); ++offset)
      72              :         {
      73        38567 :             if ((value & (kBit1 << offset)) == 0)
      74              :             {
      75         1942 :                 if (usage.compare_exchange_strong(value, value | (kBit1 << offset)))
      76              :                 {
      77          971 :                     IncreaseUsage();
      78          971 :                     return At(word * kBitChunkSize + offset);
      79              :                 }
      80              : 
      81            0 :                 value = usage.load(std::memory_order_relaxed); // if there is a race, update new usage
      82              :             }
      83              :         }
      84              :     }
      85            4 :     return nullptr;
      86              : }
      87              : 
      88          971 : void StaticAllocatorBitmap::Deallocate(void * element)
      89              : {
      90          971 :     size_t index  = IndexOf(element);
      91          971 :     size_t word   = index / kBitChunkSize;
      92          971 :     size_t offset = index - (word * kBitChunkSize);
      93              : 
      94              :     // ensure the element is in the pool
      95          971 :     VerifyOrDie(index < Capacity());
      96              : 
      97          971 :     auto value = mUsage[word].fetch_and(~(kBit1 << offset));
      98          971 :     VerifyOrDie((value & (kBit1 << offset)) != 0); // assert fail when free an unused slot
      99          971 :     DecreaseUsage();
     100          971 : }
     101              : 
     102          971 : size_t StaticAllocatorBitmap::IndexOf(void * element)
     103              : {
     104          971 :     std::ptrdiff_t diff = static_cast<uint8_t *>(element) - static_cast<uint8_t *>(mElements);
     105          971 :     VerifyOrDie(diff >= 0);
     106          971 :     VerifyOrDie(static_cast<size_t>(diff) % mElementSize == 0);
     107          971 :     auto index = static_cast<size_t>(diff) / mElementSize;
     108          971 :     VerifyOrDie(index < Capacity());
     109          971 :     return index;
     110              : }
     111              : 
     112         3850 : Loop StaticAllocatorBitmap::ForEachActiveObjectInner(void * context, Lambda lambda)
     113              : {
     114         8400 :     for (size_t word = 0; word * kBitChunkSize < Capacity(); ++word)
     115              :     {
     116         4915 :         auto & usage = mUsage[word];
     117         4915 :         auto value   = usage.load(std::memory_order_relaxed);
     118       139303 :         for (size_t offset = 0; offset < kBitChunkSize && offset + word * kBitChunkSize < Capacity(); ++offset)
     119              :         {
     120       134753 :             if ((value & (kBit1 << offset)) != 0)
     121              :             {
     122        59328 :                 if (lambda(context, At(word * kBitChunkSize + offset)) == Loop::Break)
     123          365 :                     return Loop::Break;
     124              :             }
     125              :         }
     126              :     }
     127         3485 :     return Loop::Finish;
     128              : }
     129              : 
     130           31 : size_t StaticAllocatorBitmap::FirstActiveIndex()
     131              : {
     132           31 :     size_t idx = 0;
     133           31 :     for (size_t word = 0; word * kBitChunkSize < Capacity(); ++word)
     134              :     {
     135           31 :         auto & usage = mUsage[word];
     136           31 :         auto value   = usage.load(std::memory_order_relaxed);
     137           33 :         for (size_t offset = 0; offset < kBitChunkSize && offset + word * kBitChunkSize < Capacity(); ++offset)
     138              :         {
     139           33 :             if ((value & (kBit1 << offset)) != 0)
     140              :             {
     141           31 :                 return idx;
     142              :             }
     143            2 :             idx++;
     144              :         }
     145              :     }
     146            0 :     VerifyOrDie(idx == mCapacity);
     147            0 :     return mCapacity;
     148              : }
     149              : 
     150         1474 : size_t StaticAllocatorBitmap::NextActiveIndexAfter(size_t start)
     151              : {
     152         1474 :     size_t idx = 0;
     153         1504 :     for (size_t word = 0; word * kBitChunkSize < Capacity(); ++word)
     154              :     {
     155         1474 :         auto & usage = mUsage[word];
     156         1474 :         auto value   = usage.load(std::memory_order_relaxed);
     157        38822 :         for (size_t offset = 0; offset < kBitChunkSize && offset + word * kBitChunkSize < Capacity(); ++offset)
     158              :         {
     159        38792 :             if (((value & (kBit1 << offset)) != 0) && (start < idx))
     160              :             {
     161         1444 :                 return idx;
     162              :             }
     163        37348 :             idx++;
     164              :         }
     165              :     }
     166           30 :     VerifyOrDie(idx == mCapacity);
     167           30 :     return mCapacity;
     168              : }
     169              : 
     170              : #if CHIP_SYSTEM_CONFIG_POOL_USE_HEAP
     171              : 
     172      6796174 : HeapObjectListNode * HeapObjectList::FindNode(void * object) const
     173              : {
     174     19488260 :     for (HeapObjectListNode * p = mNext; p != this; p = p->mNext)
     175              :     {
     176     19488260 :         if (p->mObject == object)
     177              :         {
     178      6796174 :             return p;
     179              :         }
     180              :     }
     181            0 :     return nullptr;
     182              : }
     183              : 
     184       236444 : Loop HeapObjectList::ForEachNode(void * context, Lambda lambda)
     185              : {
     186       236444 :     ++mIterationDepth;
     187       236444 :     Loop result            = Loop::Finish;
     188       236444 :     HeapObjectListNode * p = mNext;
     189      3873261 :     while (p != this)
     190              :     {
     191      3667471 :         if (p->mObject != nullptr)
     192              :         {
     193      3659254 :             if (lambda(context, p->mObject) == Loop::Break)
     194              :             {
     195        30654 :                 result = Loop::Break;
     196        30654 :                 break;
     197              :             }
     198              :         }
     199      3636817 :         p = p->mNext;
     200              :     }
     201       236444 :     --mIterationDepth;
     202       236444 :     CleanupDeferredReleases();
     203       236444 :     return result;
     204              : }
     205              : 
     206       237541 : void HeapObjectList::CleanupDeferredReleases()
     207              : {
     208       237541 :     if (mIterationDepth != 0 || !mHaveDeferredNodeRemovals)
     209              :     {
     210       225901 :         return;
     211              :     }
     212              :     // Remove nodes for released objects.
     213        11640 :     HeapObjectListNode * p = mNext;
     214        69596 :     while (p != this)
     215              :     {
     216        57956 :         HeapObjectListNode * next = p->mNext;
     217        57956 :         if (p->mObject == nullptr)
     218              :         {
     219        13159 :             p->Remove();
     220        13159 :             Platform::Delete(p);
     221              :         }
     222        57956 :         p = next;
     223              :     }
     224              : 
     225        11640 :     mHaveDeferredNodeRemovals = false;
     226              : }
     227              : 
     228              : #endif // CHIP_SYSTEM_CONFIG_POOL_USE_HEAP
     229              : 
     230              : } // namespace internal
     231              : } // namespace chip
        

Generated by: LCOV version 2.0-1