More heap corruption / allocator lock problems

Till Straumann strauman at SLAC.Stanford.EDU
Thu Oct 16 22:29:07 UTC 2003


Paul Neelands wrote:
> Regarding solution b)
> 
> If the special "gc" thread approach is used, how does one insure that it is
> run at an appropriate time?

What do you mean by "appropriate time"? The 'gc' thread approach guarantees
that 'free' is executed from a regular thread context with
_Thread_Dispatch_disable_level == 0 and interrupts enabled. Thus, no heap
corruption can occur and provided that enough CPU time is available for
scheduling the 'gc' task, it is also ensured that the memory is eventually
released.

> i.e. It may not free memory more quickly unless
> the "gc" thread is highest priority,

If you are concerned abouth how quickly memory is effectively released
(due to the delay that must be introduced because the allocator lock
must not be taken from a dispatch-disabled code section):

  a) you are right that this is affected by the priority of the 'gc' thread
     (for most applications this priority is probably very low - any spare
     CPU cycles are good enough)

> which ends up being effectively the
> same as the list approach but done via a thread and it's overhead.

  b) this is actually not true. Note that the 'real' free() always must
     be called from a thread context. Joel's solution delays the 'real'
     free until some other thread uses malloc/free which may result in
     the memory being released even later than when using a 'gc' thread
     at the lowest priority (but it shouldn't matter because noone needs
     it anyways).

The only objection I have to Joel's proposal is that it imposes
a burden on an 'innocent' task - something I have strong feelings
about in the context of a real-time OS. Consider the following scenario:

Task A has a high priority and is willing to incur the the deterministic
latency of executing one call to 'free()'

Task B destroys 10000 task variables - they all end up on the 'gc' list.

Task A is scheduled to run and executes what the designer believed to
be one call to 'malloc()' - however, it will end up executing 10000 times
'parasitic' free()s from the 'gc' list.

> Presumably the malloc/free list approach solves this problem and eliminates
> the additional interface complexity of solution a)
> 

There is no interface complexity. The interface doesn't change at all.


-- Till


> Paul Neelands
> 
> -----Original Message-----
> From: Joel Sherrill [mailto:joel.sherrill at OARcorp.com]
> ...
> 
>>b) free could be enhanced:
>>
>>   if 'free' is called while _Thread_Dispatch_disable_level > 0,
>>   it sends its pointer argument to a special "gc" thread which
>>   will eventually execute the real 'free'. The synchronization
>>   mechanism *must* be nonblocking, of course, to avoid the
>>   same kind of problem...
>>
>>While I feel that b) is 'hackish', it could certainly provide
>>backwards compatibility...
> 
> 
> Another simpler approach to this might be to have a list like you suggest
> but check that it is non-empty on each malloc or free when
> _Thread_Dispatch_disable_level
> is == 0.  It doesn't free memory as quickly as a gc thread would but it
> would get it into
> the heap when it matters.
> 
> 
>>RFC
>>
>>-- Till
> 
> 
> 
> 
> 
> 
> 





More information about the users mailing list