www.beck-ipc.com
www.beck-ipc.comwww.beck-ipc.com  | ImprintImprint
FAQFAQ  | SearchSearch  |
  |LoginLogin

error handler low memory

Questions and discussions about the operating system RTOS and the corresponding C-LIB.

error handler low memory

Postby Thomas Rebhan » 30.04.2020, 09:37

Hallo,

im nachfolgendem Testprogramm (mit beckheaph.lib) wird der error-handler mehrmals aufgerufen bevor die malloc-Funktion einen Null-Zeiger liefert.

Code: Select all
volatile unsigned int cnt;

void huge _pascal user_error_handler(int errorcode){
  helper_printf ("\r\nerror handler, code=%u, cnt=%u", errorcode, cnt);
}


void main(void) {
  BIOS_Install_Error_Handler(user_error_handler);

  for (cnt=0;;cnt++) {
    if (malloc (256)==NULL) {
     helper_printf ("\r\nmalloc failed, cnt=%u", cnt);
     break;
    }
  }
}


Ausgabe:
error handler, code=9, cnt=14323
error handler, code=9, cnt=14386
error handler, code=9, cnt=14393
error handler, code=9, cnt=14400
error handler, code=9, cnt=14407
error handler, code=9, cnt=14414
malloc failed, cnt=14414

Wie sind die ersten 5 Meldungen zu erklären?
Gibt es einen Workaround sie auszufiltern?

mfg
Thomas Rebhan
(SC143, RTOS 2.05)

Re: error handler low memory

Postby Jack Gatrost » 13.05.2020, 14:05

Hallo Herr Rebhan,

The BeckHeap library is invoking the allocmem() up to three times when it tries to grow the program's heap space. The allocmem() calls the system using the DOS INT 0x21 service 0x48. (That DOS service is the one making your error code 9 callback.)

From BeckHeap/heap_malloc.c ...
Code: Select all
// Private /////////////////////////////////////////////////////////////////
//
//  Routine:  _heapNew()
//
//  Purpose:  Attempt extending a some heap's space.
//
//  Input Parameters:
//     deltaBytes  -   Minimum number of new heap data bytes needed.  (DX:AX)
//
//  Return Value:
//     heapSegm -   New heap's segment, else zero.
//
///////////////////////////////////////////////////////////////////////////

STATIC WORD near _fastcall _heapNew( DWORD deltaBytes )
{
    HeapManS far *heap = NULL ;
    WORD minPara ;
    WORD maxPara ;
    WORD availPara ;
    WORD heapSegm ;
    // Pad requirements for the required HeapManS object
    deltaBytes += sizeof(HeapManS) + (PARAGRAPH_SIZE - 1) ;
    minPara = READ_OUT_MIDWORD(deltaBytes) ;
    maxPara = _heap_increment + minPara ;
    availPara = allocmem(maxPara, &heapSegm) ;
    if (availPara != ALLOC_BLOCK_OK)
    {
        if (availPara >= minPara)       //  Enough to be of interest?
        {
            maxPara = availPara ;           // If any.
            // Take what ever is available.  (Under race conditions,
            //  this could still fail.)
            availPara = allocmem(availPara, &heapSegm) ;
            if (availPara != ALLOC_BLOCK_OK)    // Lost the race?
            {
                // Last resort.
                maxPara = minPara ;
                availPara = allocmem(minPara, &heapSegm) ;
            }
        }
    }
    if (availPara == ALLOC_BLOCK_OK)        // Success?
    {
        heap = HeapManPtr(heapSegm) ;       // We have a new heap here now.
        helper_assign_mem(heap, _mainTaskId) ;

        __heap_init(heapSegm,
                    heapSegm + maxPara,     // topSegm
                    // Insert this new heap into our linked list
                    //  immediately before the existing _roverHeap
                    _roverHeap,
                    HeapManPtr(_roverHeap)->hmPrevHeap) ;
    }
    return FP_SEG(heap) ;

}   // _heapNew()


The point here is to allocate more than needed so that further allocations within the program do not need to ring the system again. But if the greedy allocation fails, then go back for only what we need right now.

Based on your trace, it appears that the second more conservative allocmem() call succeeds and the third last resort call was not needed.
Jack Gatrost
Software Development
Beck IPC GmbH

Return to RTOS


Who is online

Users browsing this forum: No registered users and 2 guests


cron