From eac15a4720dd9d514ab7d683fb68797c174293cc Mon Sep 17 00:00:00 2001 From: patacongo Date: Wed, 12 Sep 2012 15:18:56 +0000 Subject: Fix MMC/SD support for Wildfire board; Granule allocator can now be used from intrrupt handler git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@5134 7fd9a85b-ad96-42d3-883c-3090e2eb8679 --- nuttx/mm/Kconfig | 11 +++++++++++ nuttx/mm/Makefile | 4 ++-- nuttx/mm/mm_gran.h | 14 +++++++++----- nuttx/mm/mm_granalloc.c | 18 +++++++++--------- nuttx/mm/mm_granfree.c | 6 +++--- nuttx/mm/mm_graninit.c | 39 +++++---------------------------------- 6 files changed, 39 insertions(+), 53 deletions(-) (limited to 'nuttx/mm') diff --git a/nuttx/mm/Kconfig b/nuttx/mm/Kconfig index 2e5bc95db..5da12b65e 100644 --- a/nuttx/mm/Kconfig +++ b/nuttx/mm/Kconfig @@ -65,6 +65,17 @@ config GRAN_SINGLE are a few optimizations that can can be done and (2) the GRAN_HANDLE is not needed. +config GRAN_INTR + bool "Interrupt level support" + default n + depends on GRAN + ---help--- + Normally mutual exclusive access to granule allocator data is assured + using a semaphore. If this option is set then, instead, mutual + exclusion logic will disable interrupts. While this options is more + invasive to system performance, it will also support use of the granule + allocator from interrupt level logic. + config DEBUG_GRAN bool "Granule Allocator Debug" default n diff --git a/nuttx/mm/Makefile b/nuttx/mm/Makefile index 0cd28b23d..0ccf5a09a 100644 --- a/nuttx/mm/Makefile +++ b/nuttx/mm/Makefile @@ -1,7 +1,7 @@ ############################################################################ # mm/Makefile # -# Copyright (C) 2007 Gregory Nutt. All rights reserved. +# Copyright (C) 2007, 2012 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -41,7 +41,7 @@ CSRCS = mm_initialize.c mm_sem.c mm_addfreechunk.c mm_size2ndx.c mm_shrinkchunk mm_memalign.c mm_free.c mm_mallinfo.c ifeq ($(CONFIG_GRAN),y) -CSRCS += mm_graninit.c mm_granalloc.c mm_granfree.c +CSRCS += mm_graninit.c mm_granalloc.c mm_granfree.c mm_grancritical.c endif AOBJS = $(ASRCS:.S=$(OBJEXT)) diff --git a/nuttx/mm/mm_gran.h b/nuttx/mm/mm_gran.h index 4a76397c8..a4f51490d 100644 --- a/nuttx/mm/mm_gran.h +++ b/nuttx/mm/mm_gran.h @@ -45,6 +45,7 @@ #include #include +#include #include /**************************************************************************** @@ -88,7 +89,11 @@ struct gran_s { uint8_t log2gran; /* Log base 2 of the size of one granule */ uint16_t ngranules; /* The total number of (aligned) granules in the heap */ +#ifdef CONFIG_GRAN_INTR + irqstate_t irqstate; /* For exclusive access to the GAT */ +#else sem_t exclsem; /* For exclusive access to the GAT */ +#endif uintptr_t heapstart; /* The aligned start of the granule heap */ uint32_t gat[1]; /* Start of the granule allocation table */ }; @@ -108,11 +113,10 @@ extern FAR struct gran_s *g_graninfo; ****************************************************************************/ /**************************************************************************** - * Name: gran_semtake and gran_semgive + * Name: gran_enter_critical and gran_leave_critical * * Description: - * Managed semaphore for the granule allocator. gran_semgive is - * implemented as a macro. + * Critical section management for the granule allocator. * * Input Parameters: * priv - Pointer to the gran state @@ -122,7 +126,7 @@ extern FAR struct gran_s *g_graninfo; * ****************************************************************************/ -void gran_semtake(FAR struct gran_s *priv); -#define gran_semgive(p) sem_post(&(p)->exclsem); +void gran_enter_critical(FAR struct gran_s *priv); +void gran_leave_critical(FAR struct gran_s *priv); #endif /* __MM_MM_GRAN_H */ diff --git a/nuttx/mm/mm_granalloc.c b/nuttx/mm/mm_granalloc.c index 62fbc0870..e8022bf72 100644 --- a/nuttx/mm/mm_granalloc.c +++ b/nuttx/mm/mm_granalloc.c @@ -127,12 +127,12 @@ static inline FAR void *gran_common_alloc(FAR struct gran_s *priv, size_t size) { unsigned int ngranules; size_t tmpmask; - uintptr_t alloc; - uint32_t curr; - uint32_t next; - uint32_t mask; - int i; - int j; + uintptr_t alloc; + uint32_t curr; + uint32_t next; + uint32_t mask; + int i; + int j; DEBUGASSERT(priv && size <= 32 * (1 << priv->log2gran)); @@ -140,7 +140,7 @@ static inline FAR void *gran_common_alloc(FAR struct gran_s *priv, size_t size) { /* Get exclusive access to the GAT */ - gran_semtake(priv); + gran_enter_critical(priv); /* How many contiguous granules we we need to find? */ @@ -199,7 +199,7 @@ static inline FAR void *gran_common_alloc(FAR struct gran_s *priv, size_t size) /* And return the allocation address */ - gran_semgive(priv); + gran_leave_critical(priv); return (FAR void *)alloc; } @@ -221,7 +221,7 @@ static inline FAR void *gran_common_alloc(FAR struct gran_s *priv, size_t size) } } - gran_semgive(priv); + gran_leave_critical(priv); return NULL; } diff --git a/nuttx/mm/mm_granfree.c b/nuttx/mm/mm_granfree.c index 96fdda87e..aa14207f3 100644 --- a/nuttx/mm/mm_granfree.c +++ b/nuttx/mm/mm_granfree.c @@ -75,13 +75,13 @@ static inline void gran_common_free(FAR struct gran_s *priv, unsigned int granmask; unsigned int ngranules; unsigned int avail; - uint32_t gatmask; + uint32_t gatmask; DEBUGASSERT(priv && memory && size <= 32 * (1 << priv->log2gran)); /* Get exclusive access to the GAT */ - gran_semtake(priv); + gran_enter_critical(priv); /* Determine the granule number of the first granule in the allocation */ @@ -121,7 +121,7 @@ static inline void gran_common_free(FAR struct gran_s *priv, priv->gat[gatidx] &= ~(gatmask << gatbit); } - gran_semgive(priv); + gran_leave_critical(priv); } /**************************************************************************** diff --git a/nuttx/mm/mm_graninit.c b/nuttx/mm/mm_graninit.c index d3144b2aa..cde2370d0 100644 --- a/nuttx/mm/mm_graninit.c +++ b/nuttx/mm/mm_graninit.c @@ -119,7 +119,12 @@ static inline FAR struct gran_s *gran_common_initialize(FAR void *heapstart, priv->log2gran = log2gran; priv->ngranules = ngranules; priv->heapstart = alignedstart; + + /* Initialize mutual exclusion support */ + +#ifndef CONFIG_GRAN_INTR sem_init(&priv->exclsem, 0, 1); +#endif } return priv; @@ -172,38 +177,4 @@ GRAN_HANDLE gran_initialize(FAR void *heapstart, size_t heapsize, uint8_t log2gr } #endif -/**************************************************************************** - * Name: gran_semtake and gran_semgive - * - * Description: - * Managed semaphore for the granule allocator. gran_semgive is - * implemented as a macro. - * - * Input Parameters: - * priv - Pointer to the gran state - * - * Returned Value: - * None - * - ****************************************************************************/ - -void gran_semtake(FAR struct gran_s *priv) -{ - int ret; - - /* Continue waiting if we are awakened by a signal */ - - do - { - ret = sem_wait(&priv->exclsem); - if (ret < 0) - { - DEBUGASSERT(errno == EINTR); - } - } - while (ret < 0); -} - #endif /* CONFIG_GRAN */ - - -- cgit v1.2.3