Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/media/gmp/GMPSharedMemManager.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* This Source Code Form is subject to the terms of the Mozilla Public
3
 * License, v. 2.0. If a copy of the MPL was not distributed with this
4
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6
#include "GMPSharedMemManager.h"
7
#include "GMPMessageUtils.h"
8
#include "mozilla/ipc/SharedMemory.h"
9
#include "mozilla/StaticPtr.h"
10
#include "mozilla/ClearOnShutdown.h"
11
12
namespace mozilla {
13
namespace gmp {
14
15
// Really one set of pools on each side of the plugin API.
16
17
// YUV buffers go from Encoder parent to child; pool there, and then return
18
// with Decoded() frames to the Decoder parent and goes into the parent pool.
19
// Compressed (encoded) data goes from the Decoder parent to the child;
20
// pool there, and then return with Encoded() frames and goes into the parent
21
// pool.
22
bool
23
GMPSharedMemManager::MgrAllocShmem(GMPSharedMem::GMPMemoryClasses aClass, size_t aSize,
24
                                   ipc::Shmem::SharedMemory::SharedMemoryType aType,
25
                                   ipc::Shmem* aMem)
26
0
{
27
0
  mData->CheckThread();
28
0
29
0
  // first look to see if we have a free buffer large enough
30
0
  for (uint32_t i = 0; i < GetGmpFreelist(aClass).Length(); i++) {
31
0
    MOZ_ASSERT(GetGmpFreelist(aClass)[i].IsWritable());
32
0
    if (aSize <= GetGmpFreelist(aClass)[i].Size<uint8_t>()) {
33
0
      *aMem = GetGmpFreelist(aClass)[i];
34
0
      GetGmpFreelist(aClass).RemoveElementAt(i);
35
0
      return true;
36
0
    }
37
0
  }
38
0
39
0
  // Didn't find a buffer free with enough space; allocate one
40
0
  size_t pagesize = ipc::SharedMemory::SystemPageSize();
41
0
  aSize = (aSize + (pagesize-1)) & ~(pagesize-1); // round up to page size
42
0
  bool retval = Alloc(aSize, aType, aMem);
43
0
  if (retval) {
44
0
    // The allocator (or NeedsShmem call) should never return less than we ask for...
45
0
    MOZ_ASSERT(aMem->Size<uint8_t>() >= aSize);
46
0
    mData->mGmpAllocated[aClass]++;
47
0
  }
48
0
  return retval;
49
0
}
50
51
bool
52
GMPSharedMemManager::MgrDeallocShmem(GMPSharedMem::GMPMemoryClasses aClass, ipc::Shmem& aMem)
53
0
{
54
0
  mData->CheckThread();
55
0
56
0
  size_t size = aMem.Size<uint8_t>();
57
0
  size_t total = 0;
58
0
59
0
  // XXX Bug NNNNNNN Until we put better guards on ipc::shmem, verify we
60
0
  // weren't fed an shmem we already had.
61
0
  for (uint32_t i = 0; i < GetGmpFreelist(aClass).Length(); i++) {
62
0
    if (NS_WARN_IF(aMem == GetGmpFreelist(aClass)[i])) {
63
0
      // Safest to crash in this case; should never happen in normal
64
0
      // operation.
65
0
      MOZ_CRASH("Deallocating Shmem we already have in our cache!");
66
0
      //return true;
67
0
    }
68
0
  }
69
0
70
0
  // XXX This works; there are better pool algorithms.  We need to avoid
71
0
  // "falling off a cliff" with too low a number
72
0
  if (GetGmpFreelist(aClass).Length() > 10) {
73
0
    Dealloc(GetGmpFreelist(aClass)[0]);
74
0
    GetGmpFreelist(aClass).RemoveElementAt(0);
75
0
    // The allocation numbers will be fubar on the Child!
76
0
    mData->mGmpAllocated[aClass]--;
77
0
  }
78
0
  for (uint32_t i = 0; i < GetGmpFreelist(aClass).Length(); i++) {
79
0
    MOZ_ASSERT(GetGmpFreelist(aClass)[i].IsWritable());
80
0
    total += GetGmpFreelist(aClass)[i].Size<uint8_t>();
81
0
    if (size < GetGmpFreelist(aClass)[i].Size<uint8_t>()) {
82
0
      GetGmpFreelist(aClass).InsertElementAt(i, aMem);
83
0
      return true;
84
0
    }
85
0
  }
86
0
  GetGmpFreelist(aClass).AppendElement(aMem);
87
0
88
0
  return true;
89
0
}
90
91
uint32_t
92
GMPSharedMemManager::NumInUse(GMPSharedMem::GMPMemoryClasses aClass)
93
0
{
94
0
  return mData->mGmpAllocated[aClass] - GetGmpFreelist(aClass).Length();
95
0
}
96
97
} // namespace gmp
98
} // namespace mozilla