DSMCC  17.9.0
 All Data Structures Files Functions Typedefs
sbm.c
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright © 2014 The DTVKit Open Software Foundation Ltd (www.dtvkit.org)
3  * Copyright © 2004 Ocean Blue Software Ltd
4  *
5  * This file is part of a DTVKit Software Component
6  * You are permitted to copy, modify or distribute this file subject to the terms
7  * of the DTVKit 1.0 Licence which can be found in licence.txt or at www.dtvkit.org
8  *
9  * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
10  * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
11  * OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
12  *
13  * If you or your organisation is not a member of DTVKit then you have access
14  * to this source code outside of the terms of the licence agreement
15  * and you are expected to delete this and any associated files immediately.
16  * Further information on DTVKit, membership and terms can be found at www.dtvkit.org
17  *******************************************************************************/
26 /*---includes for this file--------------------------------------------------*/
27 #include <string.h>
28 
29 #include "stb_debug.h"
30 
31 #include "sbm.h"
32 
33 /*---- Constant definitions for this file-------------------------------------*/
34 
35 #define INVALID_OFFSET 0xFFFFFFFF
36 
37 /*---- Local typedef structs for this file------------------------------------*/
38 
39 typedef struct s_SbmInstance
40 {
41  F_MemFree memFree;
42  F_Locking lock;
43  F_Locking unlock;
44  void *mtx_sem;
45  U32BIT totalBuffs;
46  U8BIT *buffers;
47  U32BIT *control;
48 } S_SbmInstance;
49 
50 
51 /*---- Local (static) variable declarations for this file---------------------*/
52 /* (internal variables declared static to make them local) */
53 
54 /*---- LOCAL function definitions for this file ------------------------------*/
55 /* (internal functions declared static to make them local) */
56 
57 
58 static U32BIT FindFreeBuff1( U32BIT *control, U32BIT total )
59 {
60  U32BIT cbit, ndx, i;
61  for (ndx = 0; ndx != total; ndx++, control++)
62  {
63  for (cbit = 0x80000000, i = 31; cbit; cbit >>= 1, i--)
64  {
65  if ((cbit & *control) == 0)
66  {
67  *control |= cbit;
68  return (ndx << 5) + i;
69  }
70  }
71  }
72  return INVALID_OFFSET;
73 }
74 
75 static U32BIT FindFreeBuff2( U32BIT *control, U32BIT total )
76 {
77  U32BIT cbit, ndx, i, bndl, bndh;
78  bndl = (total >> 4); // 1/16 of total
79  bndh = (total >> 3); // 1/8 of total
80  control += bndl;
81  for (ndx = bndl; ndx != bndh; ndx++, control++)
82  {
83  for (cbit = 0x03, i = 0; cbit; cbit <<= 2, i += 2)
84  {
85  if ((cbit & *control) == 0)
86  {
87  *control |= cbit;
88  return (ndx << 5) + i;
89  }
90  }
91  }
92  control -= bndh - bndl;
93  while (bndl--)
94  {
95  control--;
96  for (cbit = 0xC0000000, i = 30; cbit; cbit >>= 2, i -= 2)
97  {
98  if ((cbit & *control) == 0)
99  {
100  *control |= cbit;
101  return (bndl << 5) + i;
102  }
103  }
104  }
105  control += bndh;
106  for (ndx = bndh; ndx != total; ndx++, control++)
107  {
108  for (cbit = 0xC0000000, i = 30; cbit; cbit >>= 2, i -= 2)
109  {
110  if ((cbit & *control) == 0)
111  {
112  *control |= cbit;
113  return (ndx << 5) + i;
114  }
115  }
116  }
117  return INVALID_OFFSET;
118 }
119 
120 static U32BIT FindFreeBuff3( U32BIT *control, U32BIT total )
121 {
122  U32BIT cbit, ndx, i, bndl, bndh;
123  bndl = (total >> 3); // 1/8 of total
124  bndh = (total >> 2); // 1/4 of total
125  control += bndl;
126  for (ndx = bndl; ndx != bndh; ndx++, control++)
127  {
128  for (cbit = 0x38000000, i = 27; cbit; cbit >>= 3, i -= 3)
129  {
130  if ((cbit & *control) == 0)
131  {
132  *control |= cbit;
133  return (ndx << 5) + i;
134  }
135  }
136  }
137  control -= bndh - bndl;
138  while (bndl--)
139  {
140  control--;
141  for (cbit = 0x38000000, i = 27; cbit; cbit >>= 3, i -= 3)
142  {
143  if ((cbit & *control) == 0)
144  {
145  *control |= cbit;
146  return (bndl << 5) + i;
147  }
148  }
149  }
150  control += bndh;
151  for (ndx = bndh; ndx != total; ndx++, control++)
152  {
153  for (cbit = 0x38000000, i = 27; cbit; cbit >>= 3, i -= 3)
154  {
155  if ((cbit & *control) == 0)
156  {
157  *control |= cbit;
158  return (ndx << 5) + i;
159  }
160  }
161  }
162  return INVALID_OFFSET;
163 }
164 
165 static U32BIT FindFreeBuff4( U32BIT *control, U32BIT total )
166 {
167  U32BIT cbit, ndx, i, bndl, bndh;
168  bndl = (total >> 2); // 1/4 of total
169  bndh = (total >> 1); // 1/2 of total
170  control += bndl;
171  for (ndx = bndl; ndx != bndh; ndx++, control++)
172  {
173  for (cbit = 0xF0000000, i = 28; cbit; cbit >>= 4, i -= 4)
174  {
175  if ((cbit & *control) == 0)
176  {
177  *control |= cbit;
178  return (ndx << 5) + i;
179  }
180  }
181  }
182  control -= bndh - bndl;
183  while (bndl--)
184  {
185  control--;
186  for (cbit = 0xF0000000, i = 28; cbit; cbit >>= 4, i -= 4)
187  {
188  if ((cbit & *control) == 0)
189  {
190  *control |= cbit;
191  return (bndl << 5) + i;
192  }
193  }
194  }
195  control += bndh;
196  for (ndx = bndh; ndx != total; ndx++, control++)
197  {
198  for (cbit = 0xF, i = 0; cbit; cbit <<= 4, i += 4)
199  {
200  if ((cbit & *control) == 0)
201  {
202  *control |= cbit;
203  return (ndx << 5) + i;
204  }
205  }
206  }
207  return INVALID_OFFSET;
208 }
209 
210 static U32BIT FindFreeBuff5( U32BIT *control, U32BIT total )
211 {
212  U32BIT cbit, ndx, i, bndl, bndh;
213  bndl = (total >> 2) + (total >> 3); // 3/8 of total
214  bndh = (total >> 1) + (total >> 3); // 5/8 of total
215  control += bndl;
216  for (ndx = bndl; ndx != bndh; ndx++, control++)
217  {
218  for (cbit = 0x3E000000, i = 25; cbit; cbit >>= 5, i -= 5)
219  {
220  if ((cbit & *control) == 0)
221  {
222  *control |= cbit;
223  return (ndx << 5) + i;
224  }
225  }
226  }
227  control -= bndh - bndl;
228  while (bndl--)
229  {
230  control--;
231  for (cbit = 0x3E000000, i = 25; cbit; cbit >>= 5, i -= 5)
232  {
233  if ((cbit & *control) == 0)
234  {
235  *control |= cbit;
236  return (bndl << 5) + i;
237  }
238  }
239  }
240  control += bndh;
241  for (ndx = bndh; ndx != total; ndx++, control++)
242  {
243  for (cbit = 0x3E000000, i = 25; cbit; cbit >>= 5, i -= 5)
244  {
245  if ((cbit & *control) == 0)
246  {
247  *control |= cbit;
248  return (ndx << 5) + i;
249  }
250  }
251  }
252  return INVALID_OFFSET;
253 }
254 
255 static U32BIT FindFreeBuff6( U32BIT *control, U32BIT total )
256 {
257  U32BIT cbit, ndx, i, bndl, bndh;
258  bndl = (total >> 1); // 1/2 of total
259  bndh = (total >> 1) + (total >> 2); // 3/4 of total
260  control += bndl;
261  for (ndx = bndl; ndx != bndh; ndx++, control++)
262  {
263  for (cbit = 0x3F000000, i = 24; cbit; cbit >>= 6, i -= 6)
264  {
265  if ((cbit & *control) == 0)
266  {
267  *control |= cbit;
268  return (ndx << 5) + i;
269  }
270  }
271  }
272  control -= bndh - bndl;
273  while (bndl--)
274  {
275  control--;
276  for (cbit = 0x3F000000, i = 24; cbit; cbit >>= 6, i -= 6)
277  {
278  if ((cbit & *control) == 0)
279  {
280  *control |= cbit;
281  return (bndl << 5) + i;
282  }
283  }
284  }
285  control += bndh;
286  for (ndx = bndh; ndx != total; ndx++, control++)
287  {
288  for (cbit = 0xFC, i = 2; cbit; cbit <<= 6, i += 6)
289  {
290  if ((cbit & *control) == 0)
291  {
292  *control |= cbit;
293  return (ndx << 5) + i;
294  }
295  }
296  }
297  return INVALID_OFFSET;
298 }
299 
300 static U32BIT FindFreeBuff7( U32BIT *control, U32BIT total )
301 {
302  U32BIT cbit, ndx, i, bndl;
303  bndl = (total >> 1) + (total >> 3); // 5/8 of total
304  control += bndl;
305  for (ndx = bndl; ndx != total; ndx++, control++)
306  {
307  for (cbit = 0xFE00000, i = 21; cbit; cbit >>= 7, i -= 7)
308  {
309  if ((cbit & *control) == 0)
310  {
311  *control |= cbit;
312  return (ndx << 5) + i;
313  }
314  }
315  }
316  control -= total - bndl;
317  while (bndl--)
318  {
319  control--;
320  for (cbit = 0x7F0, i = 4; cbit; cbit <<= 7, i += 7)
321  {
322  if ((cbit & *control) == 0)
323  {
324  *control |= cbit;
325  return (bndl << 5) + i;
326  }
327  }
328  }
329  return INVALID_OFFSET;
330 }
331 
332 static U32BIT FindFreeBuff8( U32BIT *control, U32BIT total )
333 {
334  U32BIT cbit, i;
335  control += total;
336  while (total--)
337  {
338  control--;
339  if (*control != 0xFFFFFFFF)
340  {
341  for (cbit = 0xFF, i = 0; cbit; cbit <<= 8, i += 8)
342  {
343  if ((cbit & *control) == 0)
344  {
345  *control |= cbit;
346  return (total << 5) + i;
347  }
348  }
349  }
350  }
351  return INVALID_OFFSET;
352 }
353 
354 /*---- GLOBAL function definitions for this file -----------------------------*/
355 
356 
357 /*--------------- Functions supply / release section data --------------------*/
358 
359 
360 
369 U8BIT* SBM_AllocateBuffer( H_SbmInstance sbm, U8BIT size1 )
370 {
371  U8BIT *pBuff;
372  U32BIT offset;
373  U8BIT sz;
374 
375  sz = (size1 >> 1) & 0x7;
376  sbm->lock(sbm->mtx_sem);
377  switch (sz)
378  {
379  case 0: // < 512
380  offset = FindFreeBuff1( sbm->control, sbm->totalBuffs );
381  break;
382 
383  case 1: // < 1024
384  offset = FindFreeBuff2( sbm->control, sbm->totalBuffs );
385  break;
386 
387  case 2:
388  offset = FindFreeBuff3( sbm->control, sbm->totalBuffs );
389  break;
390 
391  case 3: // < 2047
392  offset = FindFreeBuff4( sbm->control, sbm->totalBuffs );
393  break;
394 
395  case 4:
396  offset = FindFreeBuff5( sbm->control, sbm->totalBuffs );
397  break;
398 
399  case 5:
400  offset = FindFreeBuff6( sbm->control, sbm->totalBuffs );
401  break;
402 
403  case 6:
404  offset = FindFreeBuff7( sbm->control, sbm->totalBuffs );
405  break;
406 
407  case 7: // < 4096
408  offset = FindFreeBuff8( sbm->control, sbm->totalBuffs );
409  }
410  sbm->unlock(sbm->mtx_sem);
411  if (offset == INVALID_OFFSET ||
412  offset >= (sbm->totalBuffs << 5)) // this second condition should not happen
413  {
414  pBuff = NULL;
415  }
416  else
417  {
418  // scale up offset to block size of 512 bytes
419  pBuff = sbm->buffers + (offset << 9);
420  // place size1 byte in section length location (in case not done by client)
421  pBuff[1] = size1;
422  }
423  return pBuff;
424 }
425 
432 void SBM_ReleaseBuffer( H_SbmInstance sbm, U8BIT *buffer )
433 {
434  U32BIT offset, mask, shft, ndx;
435  U16BIT size;
436 
437  offset = (buffer - sbm->buffers) >> 9;
438  size = (buffer[1] & 0x0F) >> 1;
439  ndx = offset >> 5;
440  shft = offset & 0x1f;
441 
442  if (ndx < sbm->totalBuffs &&
443  (shft + size) < 32)
444  {
445  mask = (1 << (size + 1)) - 1;
446  sbm->lock(sbm->mtx_sem);
447  sbm->control[ndx] &= ~(mask << shft);
448  sbm->unlock(sbm->mtx_sem);
449  }
450 }
451 
457 H_SbmInstance SBM_CreateInstance( S_SbmSetup *pSetup )
458 {
459  S_SbmInstance *sbm = NULL;
460  U32BIT totalBuffs, csize;
461  U8BIT *buffs;
462 
463  if (pSetup != NULL)
464  {
465  if (pSetup->memAlloc != NULL &&
466  pSetup->memFree != NULL &&
467  pSetup->lock != NULL &&
468  pSetup->unlock != NULL &&
469  pSetup->mtx_sem != NULL &&
470  pSetup->bufferSize != 0)
471  {
472  buffs = NULL;
473  totalBuffs = pSetup->bufferSize;
474  while (totalBuffs)
475  {
476  buffs = pSetup->memAlloc( totalBuffs << 16 );
477  if (buffs != NULL)
478  {
479  break;
480  }
481  totalBuffs--;
482  }
483  if (buffs != NULL)
484  {
485  // scale totalBuffs to number of 16K blocks (4 * 4096)
486  totalBuffs <<= 2;
487  csize = totalBuffs * sizeof(U32BIT);
488  sbm = pSetup->memAlloc( sizeof(S_SbmInstance) + csize );
489  if (sbm == NULL)
490  {
491  pSetup->memFree( buffs );
492  }
493  else
494  {
495  sbm->memFree = pSetup->memFree;
496  sbm->lock = pSetup->lock;
497  sbm->unlock = pSetup->unlock;
498  sbm->mtx_sem = pSetup->mtx_sem;
499  sbm->totalBuffs = totalBuffs;
500  sbm->buffers = buffs;
501  sbm->control = (U32BIT *)(sbm + 1);
502  memset(sbm->control, 0, csize);
503  }
504  }
505  }
506  }
507  return sbm;
508 }
509 
517 void SBM_DestroyInstance( H_SbmInstance sbm, void **pBufMtx )
518 {
519  if (sbm)
520  {
521  #ifndef NDEBUG
522  U32BIT *control;
523  U32BIT count;
524  control = sbm->control;
525  sbm->lock(sbm->mtx_sem);
526  for (count = 0; count != sbm->totalBuffs; count++, control++)
527  {
528  if (*control != 0)
529  {
530  /* some data buffer(s) not freed! */
531  STB_SPDebugWrite("SBM ERROR: index=%d ctrl=%08x", count, *control);
532  }
533  }
534  sbm->unlock(sbm->mtx_sem);
535  #endif
536  if (pBufMtx != NULL)
537  {
538  *pBufMtx = sbm->mtx_sem;
539  }
540  sbm->memFree( sbm->buffers );
541  sbm->memFree( sbm );
542  }
543 }
544 
Interface to platform debug functions.
void STB_SPDebugWrite(const char *format,...)
Write debug string to serial/debug port. <CR><LF> characters will be automatically added to the end o...
Section Buffer Manager (for use by Section Filter Manager and client) Provides mechanism to allocate ...
Definition: sbm.h:37
H_SbmInstance SBM_CreateInstance(S_SbmSetup *pSetup)
Create Section Buffer Manager instance, using setup structure.
Definition: sbm.c:457
U8BIT * SBM_AllocateBuffer(H_SbmInstance sbm, U8BIT size1)
Allocate buffer for a DVB section.
Definition: sbm.c:369
void SBM_DestroyInstance(H_SbmInstance sbm, void **pBufMtx)
Destroy Section Filter Manager instance, and return mutexes so that they may be destroyed by client...
Definition: sbm.c:517
void SBM_ReleaseBuffer(H_SbmInstance sbm, U8BIT *buffer)
Release DVB section buffer allocated with SBM_AllocateBuffer.
Definition: sbm.c:432