diff options
Diffstat (limited to 'nuttx/sched/sched_garbage.c')
-rw-r--r-- | nuttx/sched/sched_garbage.c | 116 |
1 files changed, 87 insertions, 29 deletions
diff --git a/nuttx/sched/sched_garbage.c b/nuttx/sched/sched_garbage.c index 0eaa19247..d11a0df96 100644 --- a/nuttx/sched/sched_garbage.c +++ b/nuttx/sched/sched_garbage.c @@ -63,21 +63,10 @@ ****************************************************************************/ /**************************************************************************** - * Public Functions - ****************************************************************************/ -/**************************************************************************** - * Name: sched_garbagecollection + * Name: sched_kucleanup * * Description: - * Clean-up memory de-allocations that we queued because they could not - * be freed in that execution context (for example, if the memory was freed - * from an interrupt handler). - * - * This logic may be called from the worker thread (see work_thread.c). - * If, however, CONFIG_SCHED_WORKQUEUE is not defined, then this logic will - * be called from the IDLE thread. It is less optimal for the garbage - * collection to be called from the IDLE thread because it runs at a very - * low priority and could cause false memory out conditions. + * Clean-up deferred de-allocations of user memory * * Input parameters: * None @@ -87,7 +76,7 @@ * ****************************************************************************/ -void sched_garbagecollection(void) +static inline void sched_kucleanup(void) { irqstate_t flags; FAR void *address; @@ -96,14 +85,14 @@ void sched_garbagecollection(void) * is needed because this is an atomic test. */ - while (g_delayeddeallocations.head) + while (g_delayed_kufree.head) { /* Remove the first delayed deallocation. This is not atomic and so * we must disable interrupts around the queue operation. */ flags = irqsave(); - address = (FAR void*)sq_remfirst((FAR sq_queue_t*)&g_delayeddeallocations); + address = (FAR void*)sq_remfirst((FAR sq_queue_t*)&g_delayed_kufree); irqrestore(flags); /* The address should always be non-NULL since that was checked in the @@ -112,26 +101,95 @@ void sched_garbagecollection(void) if (address) { + /* Return the memory to the user heap */ + + kufree(address); + } + } +} + +/**************************************************************************** + * Name: sched_kcleanup + * + * Description: + * Clean-up deferred de-allocations of kernel memory + * + * Input parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + #if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP) - /* Does the address to be freed lie in the kernel heap? */ +static inline void sched_kcleanup(void) +{ + irqstate_t flags; + FAR void *address; - if (kmm_heapmember(address)) - { - /* Yes.. return the memory to the kernel heap */ + /* Test if the delayed deallocation queue is empty. No special protection + * is needed because this is an atomic test. + */ + + while (g_delayed_kfree.head) + { + /* Remove the first delayed deallocation. This is not atomic and so + * we must disable interrupts around the queue operation. + */ - kfree(address); - } + flags = irqsave(); + address = (FAR void*)sq_remfirst((FAR sq_queue_t*)&g_delayed_kfree); + irqrestore(flags); - /* No.. then the address must lie in the user heap (unchecked) */ + /* The address should always be non-NULL since that was checked in the + * 'while' condition above. + */ - else -#endif - { - /* Return the memory to the user heap */ + if (address) + { + /* Return the memory to the kernel heap */ - kufree(address); - } + kfree(address); } } } +#else +# define sched_kcleanup() +#endif +/**************************************************************************** + * Public Functions + ****************************************************************************/ +/**************************************************************************** + * Name: sched_garbagecollection + * + * Description: + * Clean-up memory de-allocations that we queued because they could not + * be freed in that execution context (for example, if the memory was freed + * from an interrupt handler). + * + * This logic may be called from the worker thread (see work_thread.c). + * If, however, CONFIG_SCHED_WORKQUEUE is not defined, then this logic will + * be called from the IDLE thread. It is less optimal for the garbage + * collection to be called from the IDLE thread because it runs at a very + * low priority and could cause false memory out conditions. + * + * Input parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sched_garbagecollection(void) +{ + /* Handle deferred deallocations for the kernel heap */ + + sched_kcleanup(); + + /* Handle deferred dealloctions for the user heap */ + + sched_kucleanup(); +} |