Spravce pameti

Jaroslav Buchta jaroslav.buchta na hascomp.cz
Čtvrtek Listopad 3 19:59:50 CET 2016


Ale ty fce malloc, free, ... je potreba resit pri multi thread 
aplikacich, klasicke knihovny maji callback funkce, u nano knihoven je 
to slozitejsi, musi se  to resit nejak takto a jeste jsou  v tom nejake 
parametry linkeru, ktere se mi nechce hledat:

size_t   __malloc_margin = 256;
char    *__brkval;

uint32_t maxHeap;
uint32_t minMSP = 0xffffffff;

void *__real__sbrk_r(
     struct _reent *r,
     ptrdiff_t incr);

void *__wrap__sbrk_r(
     struct _reent *r,
     ptrdiff_t incr)
{
     extern char end;   // provided by the linker script

     if (__brkval == 0)
         __brkval = &end;
#ifdef MMGMTDBG
     DBGUSART_dbgSendStr("sbrk: ");
     DBGUSART_dbgSendStrDec(incr);
     DBGUSART_dbgSendStrNl("");
#endif
     uint32_t mspCurr = __get_MSP();
     if (mspCurr < minMSP) minMSP = mspCurr;
     if (__brkval + incr > (char*)mspCurr - __malloc_margin)
     {
         r->_errno = ENOMEM;
         return (void*)-1;
     }

     void *ret = __brkval;
     __brkval += incr;

     maxHeap = (uint32_t)__brkval;
     return ret;
}


extern void *__real__malloc_r(
     struct _reent *r,
     size_t         size
);

void *__wrap__malloc_r(
     struct _reent *r,
     size_t         size
)
{
     vPortEnterCritical();
     void *ptr = __real__malloc_r(r, size);
#ifdef MMGMTDBG
     DBGUSART_dbgSendStr("malloc: ");
     DBGUSART_dbgSendStrDec(size);
     DBGUSART_dbgSendStr(" at: ");
     DBGUSART_dbgSendStrHex32((uint32_t)ptr);
     DBGUSART_dbgSendStrNl("");
#endif
     vPortExitCritical();
     return ptr;
}

extern void __real__free_r(
     struct _reent *r,
     void *ptr
);
void __wrap__free_r(
     struct _reent *r,
     void *ptr
)
{
     vPortEnterCritical();
#ifdef MMGMTDBG
     DBGUSART_dbgSendStr("free at: ");
     DBGUSART_dbgSendStrHex32((uint32_t)ptr);
     DBGUSART_dbgSendStrNl("");
#endif
     __real__free_r(r, ptr);
     vPortExitCritical();
}


extern void *__real__realloc_r(
     struct _reent *r,
     void          *ptr,
     size_t         size
);

extern void *__wrap__realloc_r(
     struct _reent *r,
     void          *ptr,
     size_t         size
)
{
     vPortEnterCritical();
     void *newptr = __real__realloc_r(r, ptr, size);
     vPortExitCritical();
     return newptr;
}



Dne 03.11.2016 v 19:52 Miroslav Mraz napsal(a):
> Pro lepší pochopení, jak to obvykle funguje - do vlastního malloc() a 
> free() v knihovně nemá cenu se nějak vrtat. Vlastní přidělení paměti 
> zajišťuje něco jako _sbrk(), která je volána z vnitřku toho malloc(). 
> A to je právě to místo, kterým se můžete zabývat. Samotná tato funkce 
> není složitá, je to něco jako
>
> // HEAP je definovan za .bss, stack jde proti heap dokud se nepotkaji
> extern   char   _end;        // Defined by the linker.
> //register char *  stack_ptr asm ("sp");    // takhle je to v newlib
> static inline char * stack_ptr (void) {        // pochopitelneji
>   register char * res;
>   asm volatile (
>     "mov %0,sp\r\n"        // sp do vysledku
>     :"=r"(res) :: );        // standardni zapis
>   return res;
> }
>
> const char * _sbrk (int incr) {
>   static char * heap_end;
>   char *        prev_heap_end;
>   if (heap_end == NULL) heap_end = & _end;
>   prev_heap_end = heap_end;
>   if (heap_end + incr > stack_ptr())  {
> /*
>     No a tady si uděláte co je potřeba, když
>     už není dost paměti.
> */
>     return (char *) 0;
>   }
>   heap_end += incr;
>   return (const char *) prev_heap_end;
> }
> Takhle je to (přibližně) uděláno v newlib, ale samosebou si můžete 
> definovat vlastní oblast pro haldu jak chcete.
>
> Mrazík
>
> Dne 3.11.2016 v 19:04 Jan Waclawek napsal(a):
>> Ano a nie.
>>
>> V principe by ste si mali to mnozstvo pamate vyhradenej ako heap 
>> urcit Vy,
>> ci uz priamo v linker skripte alebo jeho obdobe, alebo u klikatora na to
>> bude niekde nejake okno. Potom v runtime si mozete zistit ci to tak 
>> naozaj
>> je, ale ci bude presne kod pana kolegu Nesvacila fungovat to 
>> pochopitelne
>> zavisi od toho, ci budete mat tie iste symboly v tom linker skripte atd.
>>
>> *printf ma niekedy svoj vlastny alokator a vyhradzuje si staticky cast
>> pamate (v ktorej si potom on sam pre seba dynamicky alokuje co 
>> potrebuje,
>> to je pre Vas neviditelne a nezasahuje to do "vasho" malloc()). 
>> Musite si
>> to zistit v dokumentacii ku kniznici, ktoru pouzivate (ja viem, obvykle
>> nie je ziadna prip. zdrojaky ;-) ).
>>
>> wek
>>
> _______________________________________________
> HW-list mailing list  -  sponsored by www.HW.cz
> Hw-list na list.hw.cz
> http://list.hw.cz/mailman/listinfo/hw-list




Další informace o konferenci Hw-list