RDK Documentation (Open Sourced RDK Components)
AampMemoryUtils.cpp
Go to the documentation of this file.
1 /*
2  * If not stated otherwise in this file or this component's license file the
3  * following copyright and licenses apply:
4  *
5  * Copyright 2020 RDK Management
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 /**
21  * @file AampMemoryUtils.cpp
22  * @brief Helper functions for memory management
23  */
24 
25 #include "AampMemoryUtils.h"
26 #include "AampConfig.h"
27 #include <assert.h>
28 #include <glib.h>
29 #include <errno.h>
30 
31 static int gNetMemoryCount;
32 static int gNetMemoryHighWatermark;
33 
34 static void NETMEMORY_PLUS( void )
35 {
36  gNetMemoryCount++;
37  if( gNetMemoryCount>gNetMemoryHighWatermark )
38  {
39  gNetMemoryHighWatermark = gNetMemoryCount;
40  AAMPLOG_WARN( "***gNetMemoryHighWatermark=%d", gNetMemoryHighWatermark );
41  }
42 }
43 
44 static void NETMEMORY_MINUS( void )
45 {
46  gNetMemoryCount--;
47  if( gNetMemoryCount==0 )
48  {
49  AAMPLOG_WARN( "***gNetMemoryCount=0" );
50  }
51 }
52 
53 /**
54  * @brief wrapper for g_free, used for segment allocation
55  */
56 void aamp_Free( void *ptr )
57 {
58  if( ptr )
59  {
60  NETMEMORY_MINUS();
61  g_free( ptr );
62  }
63 }
64 
65 /**
66  * @brief wrapper for g_malloc, used for segment allocation
67  */
68 void *aamp_Malloc( size_t numBytes )
69 {
70  void *ptr = g_malloc(numBytes);
71  if( ptr )
72  {
73  NETMEMORY_PLUS();
74  }
75  return ptr;
76 }
77 
78 /**
79  * @brief called when ownership of memory of injected fragments passed to gstreamer
80  */
81 void aamp_TransferMemory( void *ptr )
82 {
83  if( ptr )
84  {
85  NETMEMORY_MINUS();
86  }
87 }
88 
89 /**
90  * @brief free "GrowableBuffer" memopry allocated by aamp_Malloc
91  */
92 void aamp_Free(struct GrowableBuffer *buffer)
93 {
94  if( buffer )
95  {
96  if( buffer->ptr )
97  {
98  NETMEMORY_MINUS();
99  }
100  g_free( buffer->ptr );
101  buffer->ptr = NULL;
102  }
103 }
104 
105 /**
106  * @brief append data to GrowableBuffer ADT
107  */
108 void aamp_AppendBytes(struct GrowableBuffer *buffer, const void *ptr, size_t len)
109 {
110  size_t required = buffer->len + len;
111  if (required > buffer->avail)
112  {
113  // For encoded contents, step by step increment 512KB => 1MB => 2MB => ..
114  // In other cases, double the buffer based on availability and requirement.
115  buffer->avail = ((buffer->avail * 2) > required) ? (buffer->avail * 2) : (required * 2);
116  if( buffer->avail && !buffer->ptr )
117  { // first allocation
118  NETMEMORY_PLUS();
119  }
120  buffer->ptr = (char *)g_realloc(buffer->ptr, buffer->avail);
121  }
122  if (buffer->ptr)
123  {
124  memcpy(&buffer->ptr[buffer->len], ptr, len);
125  buffer->len = required;
126  }
127 }
128 
129 /**
130  * @brief Move data to buffer
131  */
132 void aamp_MoveBytes(struct GrowableBuffer *buffer, const void *ptr, size_t len)
133 {
134  /* remove parsed data from memory */
135  if (buffer->ptr && ptr)
136  {
137  if(buffer->avail >= len)
138  {
139  memmove(&buffer->ptr[0], ptr, len);
140  buffer->len = len;
141  }
142  else
143  {
144  AAMPLOG_ERR("bad arg(len=%zu > available)", len );
145  }
146  }
147  else
148  {
149  AAMPLOG_ERR("bad arg(NULL)");
150  }
151 }
152 
153 /**
154  * @brief Append nul character to buffer
155  */
157 {
158  char zeros[2] = { 0, 0 }; // append two bytes, to distinguish between internal inserted 0x00's and a final 0x00 0x00
159  aamp_AppendBytes(buffer, zeros, 2);
160 }
161 
162 #ifdef USE_SECMANAGER
163 
164 /**
165  * @brief Creates shared memory and provides the key
166  */
167 void * aamp_CreateSharedMem( size_t shmLen, key_t & shmKey)
168 {
169  void *shmPointer = NULL;
170  if( shmLen > 0)
171  {
172  for( int retryCount=0; retryCount<SHMGET_RETRY_MAX; retryCount++ )
173  {
174  // generate pseudo-random value to use as a unique key
175  shmKey = rand() + 1; // must be non-zero to allow access to non-child processes
176 
177  // allocate memory segment and identifier
178  int shmId = shmget(shmKey, shmLen,
179  IPC_CREAT | // create new segment
180  IPC_EXCL | // fail if already exists
181  SHM_ACCESS_PERMISSION); // owner, group, other permissions
182  if (shmId != -1 )
183  { // map newly allocated segment to shared memory pointer
184  shmPointer = shmat(shmId, NULL, 0 );
185  if( shmPointer != (void *)-1 )
186  { // success!
187  AAMPLOG_WARN("%s:%d Shared memory shmId=%d ptr=%p created for the key, %u\n",
188  __FUNCTION__, __LINE__, shmId, shmPointer, shmKey);
189  }
190  else
191  {
192  AAMPLOG_ERR("%s:%d shmat err=%d shmId=%d\n", __FUNCTION__, __LINE__, errno, shmId );
193  aamp_CleanUpSharedMem( shmPointer, shmKey, shmLen);
194  shmPointer = NULL;
195  }
196  break;
197  }
198  else
199  {
200  AAMPLOG_ERR("%s:%d shmget err=%d", __FUNCTION__, __LINE__, errno);
201  }
202  }
203  }
204  else
205  {
206  AAMPLOG_ERR("%s:%d invalid shmLen=%zu", __FUNCTION__, __LINE__, shmLen);
207  }
208  return shmPointer;
209 }
210 
211 /**
212  * @brief Detatch and delete shared memory
213  */
214 void aamp_CleanUpSharedMem(void* shmPointer, key_t shmKey, size_t shmLen)
215 {
216  if( NULL != shmPointer && (void*)-1 != shmPointer)
217  { // detach shared memory
218  if( -1 == shmdt(shmPointer) )
219  {
220  AAMPLOG_ERR("%s:%d shmdt failure %d for key %u \n", __FUNCTION__, __LINE__, errno, shmKey);
221  }
222  int shmId = shmget(shmKey, shmLen, SHM_ACCESS_PERMISSION);
223  if( shmId != -1 )
224  { // mark segment to be destroyed
225  if( -1 == shmctl(shmId, IPC_RMID, NULL) )
226  {
227  AAMPLOG_ERR("%s:%d shmctl err=%d shmId=%d\n", __FUNCTION__, __LINE__, errno, shmId );
228  }
229  }
230  else
231  {
232  AAMPLOG_ERR("%s:%d bad shmKey=%u\n", __FUNCTION__, __LINE__, shmKey);
233  }
234  }
235  else
236  {
237  AAMPLOG_ERR("%s:%d bad shmPointer=%p\n", __FUNCTION__, __LINE__, shmPointer );
238  }
239 }
240 
241 #endif
aamp_Free
void aamp_Free(void *ptr)
wrapper for g_free, used for segment allocation
Definition: AampMemoryUtils.cpp:56
aamp_MoveBytes
void aamp_MoveBytes(struct GrowableBuffer *buffer, const void *ptr, size_t len)
Move data to buffer.
Definition: AampMemoryUtils.cpp:132
aamp_Malloc
void * aamp_Malloc(size_t numBytes)
wrapper for g_malloc, used for segment allocation
Definition: AampMemoryUtils.cpp:68
aamp_AppendNulTerminator
void aamp_AppendNulTerminator(struct GrowableBuffer *buffer)
Append nul character to buffer.
Definition: AampMemoryUtils.cpp:156
AampMemoryUtils.h
Header file of helper functions for memory management.
AampConfig.h
Configurations for AAMP.
aamp_TransferMemory
void aamp_TransferMemory(void *ptr)
called when ownership of memory of injected fragments passed to gstreamer
Definition: AampMemoryUtils.cpp:81
GrowableBuffer
Structure of GrowableBuffer.
Definition: AampMemoryUtils.h:39
aamp_AppendBytes
void aamp_AppendBytes(struct GrowableBuffer *buffer, const void *ptr, size_t len)
append data to GrowableBuffer ADT
Definition: AampMemoryUtils.cpp:108