• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ------------------------------------------------------------------
2  * Copyright (C) 1998-2009 PacketVideo
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13  * express or implied.
14  * See the License for the specific language governing permissions
15  * and limitations under the License.
16  * -------------------------------------------------------------------
17  */
18 /**
19  *  @file pvmf_pool_buffer_allocator.h
20  *  @brief This file defines the PV Multimedia Framework (PVMF) media message
21  *  header class which is used to hold the basic information such as timestamp,
22  *  sequence number, etc for every media message.
23  *
24  */
25 #include "pvlogger.h"
26 #include "pvmf_pool_buffer_allocator.h"
27 #include "oscl_mem.h"
28 #include "oscl_time.h"
29 
PVMFBufferPoolAllocator(bool aLeaveOnAllocFailure)30 OSCL_EXPORT_REF PVMFBufferPoolAllocator::PVMFBufferPoolAllocator(bool aLeaveOnAllocFailure) :
31         iFragSize(0),
32         iDestroyPool(false),
33         iLeaveOnAllocFailure(aLeaveOnAllocFailure)
34 {
35     iLogger = PVLogger::GetLoggerObject("pvmf.bufferpoolallocator");
36     iAllocNum = 0;
37     iFailFrequency = 0;
38 }
39 
~PVMFBufferPoolAllocator()40 OSCL_EXPORT_REF PVMFBufferPoolAllocator::~PVMFBufferPoolAllocator()
41 {
42     iDestroyPool = true;
43     iAvailFragments.clear();
44 }
45 
SetLeaveOnAllocFailure(bool aLeaveOnAllocFailure)46 OSCL_EXPORT_REF void PVMFBufferPoolAllocator::SetLeaveOnAllocFailure(bool aLeaveOnAllocFailure)
47 {
48     iLeaveOnAllocFailure = aLeaveOnAllocFailure;
49 }
50 
size(uint16 num_frags,uint16 frag_size)51 OSCL_EXPORT_REF void PVMFBufferPoolAllocator::size(uint16 num_frags, uint16 frag_size)
52 {
53     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFBufferPoolAllocator::size num_frags(%d), frag_size(%d)", num_frags, frag_size));
54     iFragSize = frag_size;
55     iAvailFragments.reserve(num_frags);
56 
57     for (uint16 frag_num = 0; frag_num < num_frags; frag_num++)
58     {
59         unsigned aligned_refcnt_size = oscl_mem_aligned_size(sizeof(OsclRefCounterDA));
60         uint8* buf = (uint8*)OSCL_MALLOC(aligned_refcnt_size + frag_size);
61 
62         // check for out-of-memory
63         if (!buf)
64         {
65             iAvailFragments.clear();
66             OSCL_LEAVE(OSCL_BAD_ALLOC_EXCEPTION_CODE);
67         }
68 
69         // ref counter will delete itself when refcount goes to 0
70         OsclRefCounterDA* ref_counter = OSCL_PLACEMENT_NEW(buf, OsclRefCounterDA(buf, this));
71         OsclMemoryFragment m;
72         m.ptr = buf + aligned_refcnt_size;
73         m.len = iFragSize;
74         OsclRefCounterMemFrag frag(m, ref_counter, iFragSize);
75         iAvailFragments.push_back(frag);
76     }
77 }
78 
clear()79 OSCL_EXPORT_REF void PVMFBufferPoolAllocator::clear()
80 {
81     iDestroyPool = true;
82     iAvailFragments.clear();
83 }
84 
destruct_and_dealloc(OsclAny * ptr)85 OSCL_EXPORT_REF void PVMFBufferPoolAllocator::destruct_and_dealloc(OsclAny* ptr)
86 {
87     if (!iDestroyPool)
88     {
89         // Create another ref counter for the buffer and add it back to the available list
90         OsclRefCounterDA* ref_counter = OSCL_PLACEMENT_NEW(ptr, OsclRefCounterDA(ptr, this));
91         unsigned aligned_refcnt_size = oscl_mem_aligned_size(sizeof(OsclRefCounterDA));
92         OsclMemoryFragment m;
93         m.ptr = (uint8*)ptr + aligned_refcnt_size;
94         m.len = iFragSize;
95         OsclRefCounterMemFrag frag(m, ref_counter, iFragSize);
96         release(frag);
97     }
98     else
99     {
100         OSCL_FREE(ptr);
101     }
102 }
103 
get()104 OSCL_EXPORT_REF OsclRefCounterMemFrag PVMFBufferPoolAllocator::get()
105 {
106     OsclRefCounterMemFrag ret;
107 #if _DEBUG
108     ++iAllocNum;
109     if (iFailFrequency)
110     {
111         TimeValue timenow;
112         int ms = timenow.to_msec();
113         if (iAllocNum % ((ms & 0xF) + 1) == 0)
114         {
115             // throw exception
116             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NONFATAL_ERROR, (0, "PVMFBufferPoolAllocator::get - Simulating out of fragment exception !! \n"));
117             if (iLeaveOnAllocFailure)
118             {
119                 OSCL_LEAVE(OSCL_BAD_ALLOC_EXCEPTION_CODE);
120             }
121             return ret;
122         }
123     }
124 #endif
125 
126     if (!iAvailFragments.empty())
127     {
128         ret = iAvailFragments.back();
129         iAvailFragments.pop_back();
130         ret.getMemFrag().len = iFragSize;
131         return ret;
132     }
133     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_NONFATAL_ERROR, (0, "PVMFBufferPoolAllocator::get - Out of fragments !! \n"));
134 
135     if (iLeaveOnAllocFailure)
136     {
137         OSCL_LEAVE(OSCL_BAD_ALLOC_EXCEPTION_CODE);
138     }
139     return ret;
140 }
141 
release(OsclRefCounterMemFrag & frag)142 OSCL_EXPORT_REF void PVMFBufferPoolAllocator::release(OsclRefCounterMemFrag& frag)
143 {
144     iAvailFragments.push_back(frag);
145 }
146 
SetFailFrequency(uint16 aFrequency)147 OSCL_EXPORT_REF void PVMFBufferPoolAllocator::SetFailFrequency(uint16 aFrequency)
148 {
149     iFailFrequency = aFrequency;
150 }
151 
152