1 /*!
2 * \copy
3 * Copyright (c) 2013, Cisco Systems
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 */
32
33 #include <stdlib.h>
34 #include <string.h>
35 #include "memory_align.h"
36 #include "macros.h"
37
38 namespace WelsCommon {
39
40 #ifdef MEMORY_CHECK
41 static FILE* fpMemChkPoint;
42 static uint32_t nCountRequestNum;
43 static int32_t g_iMemoryLength;
44 #endif
45
46
CMemoryAlign(const uint32_t kuiCacheLineSize)47 CMemoryAlign::CMemoryAlign (const uint32_t kuiCacheLineSize)
48 #ifdef MEMORY_MONITOR
49 : m_nMemoryUsageInBytes (0)
50 #endif//MEMORY_MONITOR
51 {
52 if ((kuiCacheLineSize == 0) || (kuiCacheLineSize & 0x0f))
53 m_nCacheLineSize = 0x10;
54 else
55 m_nCacheLineSize = kuiCacheLineSize;
56 }
57
~CMemoryAlign()58 CMemoryAlign::~CMemoryAlign() {
59 #ifdef MEMORY_MONITOR
60 assert (m_nMemoryUsageInBytes == 0);
61 #endif//MEMORY_MONITOR
62 }
63
WelsMalloc(const uint32_t kuiSize,const char * kpTag,const uint32_t kiAlign)64 void* WelsMalloc (const uint32_t kuiSize, const char* kpTag, const uint32_t kiAlign) {
65 const uint32_t kiSizeOfVoidPointer = sizeof (void**);
66 const uint32_t kiSizeOfInt = sizeof (int32_t);
67 const uint32_t kiAlignedBytes = kiAlign - 1;
68 const uint32_t kiTrialRequestedSize = kuiSize + kiAlignedBytes + kiSizeOfVoidPointer + kiSizeOfInt;
69 const uint32_t kiActualRequestedSize = kiTrialRequestedSize;
70 const uint32_t kiPayloadSize = kuiSize;
71
72 uint8_t* pBuf = (uint8_t*) malloc (kiActualRequestedSize);
73 if (NULL == pBuf)
74 return NULL;
75
76 #ifdef MEMORY_CHECK
77 if (fpMemChkPoint == NULL) {
78 fpMemChkPoint = fopen ("./enc_mem_check_point.txt", "at+");
79 nCountRequestNum = 0;
80 }
81
82 if (fpMemChkPoint != NULL) {
83 if (kpTag != NULL)
84 fprintf (fpMemChkPoint, "WelsMalloc(), 0x%x : actual uiSize:\t%d\tbytes, input uiSize: %d bytes, %d - %s\n",
85 (void*)pBuf, kiActualRequestedSize, kuiSize, nCountRequestNum++, kpTag);
86 else
87 fprintf (fpMemChkPoint, "WelsMalloc(), 0x%x : actual uiSize:\t%d\tbytes, input uiSize: %d bytes, %d \n", (void*)pBuf,
88 kiActualRequestedSize, kuiSize, nCountRequestNum++);
89 fflush (fpMemChkPoint);
90 }
91 #endif
92 uint8_t* pAlignedBuffer;
93 pAlignedBuffer = pBuf + kiAlignedBytes + kiSizeOfVoidPointer + kiSizeOfInt;
94 pAlignedBuffer -= ((uintptr_t) pAlignedBuffer & kiAlignedBytes);
95 * ((void**) (pAlignedBuffer - kiSizeOfVoidPointer)) = pBuf;
96 * ((int32_t*) (pAlignedBuffer - (kiSizeOfVoidPointer + kiSizeOfInt))) = kiPayloadSize;
97
98 return pAlignedBuffer;
99 }
100
WelsFree(void * pPointer,const char * kpTag)101 void WelsFree (void* pPointer, const char* kpTag) {
102 if (pPointer) {
103 #ifdef MEMORY_CHECK
104 if (fpMemChkPoint != NULL) {
105 if (kpTag != NULL)
106 fprintf (fpMemChkPoint, "WelsFree(), 0x%x - %s: \t%d\t bytes \n", (void*) (* (((void**) pPointer) - 1)), kpTag,
107 g_iMemoryLength);
108 else
109 fprintf (fpMemChkPoint, "WelsFree(), 0x%x \n", (void*) (* (((void**) pPointer) - 1)));
110 fflush (fpMemChkPoint);
111 }
112 #endif
113 free (* (((void**) pPointer) - 1));
114 }
115 }
116
WelsMallocz(const uint32_t kuiSize,const char * kpTag)117 void* CMemoryAlign::WelsMallocz (const uint32_t kuiSize, const char* kpTag) {
118 void* pPointer = WelsMalloc (kuiSize, kpTag);
119 if (NULL == pPointer) {
120 return NULL;
121 }
122 // zero memory
123 memset (pPointer, 0, kuiSize);
124
125 return pPointer;
126 }
127
WelsMalloc(const uint32_t kuiSize,const char * kpTag)128 void* CMemoryAlign::WelsMalloc (const uint32_t kuiSize, const char* kpTag) {
129 void* pPointer = WelsCommon::WelsMalloc (kuiSize, kpTag, m_nCacheLineSize);
130 #ifdef MEMORY_MONITOR
131 if (pPointer != NULL) {
132 const int32_t kiMemoryLength = * ((int32_t*) ((uint8_t*)pPointer - sizeof (void**) - sizeof (
133 int32_t))) + m_nCacheLineSize - 1 + sizeof (void**) + sizeof (int32_t);
134 m_nMemoryUsageInBytes += kiMemoryLength;
135 #ifdef MEMORY_CHECK
136 g_iMemoryLength = kiMemoryLength;
137 #endif
138 }
139 #endif//MEMORY_MONITOR
140 return pPointer;
141 }
142
WelsFree(void * pPointer,const char * kpTag)143 void CMemoryAlign::WelsFree (void* pPointer, const char* kpTag) {
144 #ifdef MEMORY_MONITOR
145 if (pPointer) {
146 const int32_t kiMemoryLength = * ((int32_t*) ((uint8_t*)pPointer - sizeof (void**) - sizeof (
147 int32_t))) + m_nCacheLineSize - 1 + sizeof (void**) + sizeof (int32_t);
148 m_nMemoryUsageInBytes -= kiMemoryLength;
149 #ifdef MEMORY_CHECK
150 g_iMemoryLength = kiMemoryLength;
151 #endif
152 }
153 #endif//MEMORY_MONITOR
154 WelsCommon::WelsFree (pPointer, kpTag);
155 }
156
WelsMallocz(const uint32_t kuiSize,const char * kpTag)157 void* WelsMallocz (const uint32_t kuiSize, const char* kpTag) {
158 void* pPointer = WelsMalloc (kuiSize, kpTag, 16);
159 if (NULL == pPointer) {
160 return NULL;
161 }
162 memset (pPointer, 0, kuiSize);
163 return pPointer;
164 }
165
WelsGetCacheLineSize() const166 const uint32_t CMemoryAlign::WelsGetCacheLineSize() const {
167 return m_nCacheLineSize;
168 }
169
WelsGetMemoryUsage() const170 const uint32_t CMemoryAlign::WelsGetMemoryUsage() const {
171 return m_nMemoryUsageInBytes;
172 }
173
174 } // end of namespace WelsCommon
175