This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

HeapMemMP_alloc clarification

Other Parts Discussed in Thread: SYSBIOS

sysbios 6.34.03.19, ipc 1.25.1.9

The documentation suggests that HeapMemMP_alloc just returns NULL if the allocation isn't possible, and to me this is the correct behavior.  However, it is also raising an error (E_memory).  To me, this is broken.  A heap can be used in many contexts, and only the client can decide if a failed allocation is an error to be reported, or just a situation that must be handled.  For instance, in my case, I'm not calling HeapMemMP_alloc directly-- it's being called by MessageQ_alloc, which is being called in the idiomatic loop

while ((msg = MessageQ_alloc(...)) != NULL)

    Task_sleep(n);

I'm ok with blocking when the heap is full and I know that (barring total breakdown) eventually the allocation will succeed (or the Task will be made inactive).

I'm hoping you agree and will fix this.

Thanks

  • Are you objecting to the error message that is printed when the HeapMemMP_alloc() fails?

    If so, this behavior can be suppressed in your config file by adding these lines:

        var Error = xdc.useModule('xdc.runtime.Error');
        Error.raiseHook = null;

    The default Error.raiseHook function is 'Error.print' which simply prints out an informative error message.

    Alan

  • Alan DeMars said:

    Are you objecting to the error message that is printed when the HeapMemMP_alloc() fails?

    If so, this behavior can be suppressed in your config file by adding these lines:

        var Error = xdc.useModule('xdc.runtime.Error');
        Error.raiseHook = null;

    The default Error.raiseHook function is 'Error.print' which simply prints out an informative error message.

    I'm looking for confirmation that you (TI) agree that this is a bug.

    If it is a bug, please fix it and in the meantime I will fix the source locally.

    If you don't agree it is a bug, please correct the documentation, and then explain how you expect someone to use MessageQ_alloc.

    Hopefully you presented your "workaround" merely to indicate the existence of Error_raiseHook.  A safer workaround is something like:

    MessageQ_Msg MyMessageQ_alloc(UInt16 heapId, UInt32 size)

    {

      // take a lock

      msgs_disabled_to_workaround_spurious_errors_from_ipc = true;

      MessageQ_Msg msg = MessageQ_alloc(heapId, size);

      msgs_disabled_to_workaround_spurious_errors_from_ipc = false;

      // release the lock

      return msg;

    }

    Void MyErrorRasiseHook(Error_Block* eb)

    {

      if (!msgs_disabled_to_workaround_spurious_errors_from_ipc || !ErrorMatchesInternalCodeFromHeapAlloc(eb))

      {

        Error_print(eb);

      }
    }

    Thanks

  • There have been a couple of point releases since I brought this up, and still no statement from TI.  Can you please state whether you agree that this is a bug or you consider it the intended behavior.

    Thank you,

    Elron

  • Elron,

    This is the inteded behavior.  There is no bug here.  The Error_raise() is defaulted to print a message but this should have no bearing functionally on your program (other than prints to the console aren't real-time calls).  If you don't want any prints statements for the Error_raise() you can do what was suggested above.  In a real system, you don't want Error_raise() do be calling print.

    Yes, you can call MessageQ_alloc() in a loop as you showed earlier but there are times when you don't want to do MessageQ_alloc() in a loop.  Lets say processor 0 sends a message to processor 1.  If its a copy based MessageQ transport, then Processor 1 does a MessageQ_alloc() and there better be one message buffer available else that message is lost.

    Judah

  • Ok, I'll deal with it, but

    judahvang said:
    Yes, you can call MessageQ_alloc() in a loop as you showed earlier but there are times when you don't want to do MessageQ_alloc() in a loop.  Lets say processor 0 sends a message to processor 1.  If its a copy based MessageQ transport, then Processor 1 does a MessageQ_alloc() and there better be one message buffer available else that message is lost.

    I think this is a weak argument.  Only the client can decide if unavailable memory is an error condition or a valid state.  MessageQ_alloc returns null if the request isn't possible, so clients like the one you describe can raise an error or do whatever they want in that situation.

    In my "real system," I do want Error_raise to do (something like) print.  Real errors happen in the field, and I want them reported.  I don't want fake errors reported though, nor do our customers.  I definitely want Error_raise to print in development builds, but those prints aren't very useful if they are overshadowed by a flood of fake error messages.

    You could also imagine a situation where a client wants Error_raise to shut down the whole system and wait for a postmortem. 

    Special-casing errors raised just from MessageQ_alloc (or Memory_alloc) is fragile at best, and I'm not even sure it's possible (does the ErrorBlock indicate from which heap and which Task the allocation failure happened?).

    At the very least you should update the documentation to specify Error_raise as an effect of the function if the allocation fails.

    Elron