tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ShmemPool.cpp (2599B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set sw=2 ts=8 et ft=cpp : */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
      5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "mozilla/ShmemPool.h"
      8 
      9 #include <utility>
     10 
     11 #include "mozilla/Assertions.h"
     12 #include "mozilla/Logging.h"
     13 
     14 mozilla::LazyLogModule sShmemPoolLog("ShmemPool");
     15 
     16 #define SHMEMPOOL_LOG_VERBOSE(args) \
     17  MOZ_LOG(sShmemPoolLog, mozilla::LogLevel::Verbose, args)
     18 
     19 namespace mozilla {
     20 
     21 ShmemPool::ShmemPool(size_t aPoolSize, PoolType aPoolType)
     22    : mPoolType(aPoolType),
     23      mMutex("mozilla::ShmemPool"),
     24      mPoolFree(aPoolSize),
     25      mErrorLogged(false)
     26 #ifdef DEBUG
     27      ,
     28      mMaxPoolUse(0)
     29 #endif
     30 {
     31  mShmemPool.SetLength(aPoolSize);
     32 }
     33 
     34 mozilla::ShmemBuffer ShmemPool::GetIfAvailable(size_t aSize) {
     35  MutexAutoLock lock(mMutex);
     36 
     37  // Pool is empty, don't block caller.
     38  if (mPoolFree == 0) {
     39    if (!mErrorLogged) {
     40      // log "out of pool" once as error to avoid log spam
     41      mErrorLogged = true;
     42      SHMEMPOOL_LOG_ERROR(
     43          ("ShmemPool is empty, future occurrences "
     44           "will be logged as warnings"));
     45    } else {
     46      SHMEMPOOL_LOG_WARN(("ShmemPool is empty"));
     47    }
     48    // This isn't initialized, so will be understood as an error.
     49    return ShmemBuffer();
     50  }
     51 
     52  ShmemBuffer& res = mShmemPool[mPoolFree - 1];
     53 
     54  if (!res.mInitialized) {
     55    SHMEMPOOL_LOG(("No free preallocated Shmem"));
     56    return ShmemBuffer();
     57  }
     58 
     59  MOZ_ASSERT(res.mShmem.IsWritable(), "Pool in Shmem is not writable?");
     60 
     61  if (res.mShmem.Size<uint8_t>() < aSize) {
     62    SHMEMPOOL_LOG(("Free Shmem but not of the right size"));
     63    return ShmemBuffer();
     64  }
     65 
     66  mPoolFree--;
     67 #ifdef DEBUG
     68  size_t poolUse = mShmemPool.Length() - mPoolFree;
     69  if (poolUse > mMaxPoolUse) {
     70    mMaxPoolUse = poolUse;
     71    SHMEMPOOL_LOG(
     72        ("Maximum ShmemPool use increased: %zu buffers", mMaxPoolUse));
     73  }
     74 #endif
     75  return std::move(res);
     76 }
     77 
     78 void ShmemPool::Put(ShmemBuffer&& aShmem) {
     79  MutexAutoLock lock(mMutex);
     80  MOZ_ASSERT(mPoolFree < mShmemPool.Length());
     81  mShmemPool[mPoolFree] = std::move(aShmem);
     82  mPoolFree++;
     83 #ifdef DEBUG
     84  size_t poolUse = mShmemPool.Length() - mPoolFree;
     85  if (poolUse > 0) {
     86    SHMEMPOOL_LOG_VERBOSE(("ShmemPool usage reduced to %zu buffers", poolUse));
     87  }
     88 #endif
     89 }
     90 
     91 ShmemPool::~ShmemPool() {
     92 #ifdef DEBUG
     93  for (size_t i = 0; i < mShmemPool.Length(); i++) {
     94    MOZ_ASSERT(!mShmemPool[i].Valid());
     95  }
     96 #endif
     97 }
     98 
     99 }  // namespace mozilla