From patchwork Fri Jan 4 17:12:33 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: acpica: fwts_acpica: optimise semaphore tracking Date: Fri, 04 Jan 2013 07:12:33 -0000 From: Colin King X-Patchwork-Id: 209493 Message-Id: <1357319553-24060-1-git-send-email-colin.king@canonical.com> To: fwts-devel@lists.ubuntu.com From: Colin Ian King The original semaphore tracking kept a track of semaphores used by ACPICA by keeping a hash table. Remove this overhead and just have a static table of pre-allocated semaphores. This removes the need to allocate and free semaphores for Create/Destroy operation. Also make the locking around this structure more restrictive to ensure no race issues can occur. Signed-off-by: Colin Ian King Acked-by: Keng-Yu Lin Acked-by: Ivan Hu --- src/acpica/fwts_acpica.c | 152 +++++++++++++++++++---------------------------- 1 file changed, 61 insertions(+), 91 deletions(-) diff --git a/src/acpica/fwts_acpica.c b/src/acpica/fwts_acpica.c index d177401..2c489f1 100644 --- a/src/acpica/fwts_acpica.c +++ b/src/acpica/fwts_acpica.c @@ -31,7 +31,7 @@ #include #include -static pthread_mutex_t mutex_lock_count; +static pthread_mutex_t mutex_lock_sem_table; static pthread_mutex_t mutex_thread_info; #include "fwts.h" @@ -52,15 +52,14 @@ static pthread_mutex_t mutex_thread_info; #define ACPI_MAX_INIT_TABLES (32) #define AEXEC_NUM_REGIONS (8) -#define MAX_SEMAPHORES (1009) -#define HASH_FULL (0xffffffff) - +#define MAX_SEMAPHORES (1024) #define MAX_THREADS (128) typedef struct { - sem_t *sem; /* Semaphore handle */ + sem_t sem; /* Semaphore handle */ int count; /* count > 0 if acquired */ -} sem_hash; + bool used; /* Semaphore being used flag */ +} sem_info; typedef void * (*PTHREAD_CALLBACK)(void *); @@ -68,9 +67,9 @@ BOOLEAN AcpiGbl_IgnoreErrors = FALSE; UINT8 AcpiGbl_RegionFillValue = 0; /* - * Hash table of semaphore handles + * Used to account for semaphores used by AcpiOs*Semaphore() */ -static sem_hash sem_hash_table[MAX_SEMAPHORES]; +static sem_info sem_table[MAX_SEMAPHORES]; static ACPI_TABLE_DESC Tables[ACPI_MAX_INIT_TABLES]; @@ -129,14 +128,12 @@ void fwts_acpica_sem_count_clear(void) { int i; - pthread_mutex_lock(&mutex_lock_count); + pthread_mutex_lock(&mutex_lock_sem_table); - for (i=0;iused = true; + sem->count = 0; - *OutHandle = (ACPI_HANDLE)sem; + if (sem_init(&sem->sem, 0, InitialUnits) == -1) { + *OutHandle = NULL; + ret = AE_NO_MEMORY; + } else { + *OutHandle = (ACPI_HANDLE)sem; + } + pthread_mutex_unlock(&mutex_lock_sem_table); - return AE_OK; + return ret; } /* @@ -580,17 +541,20 @@ ACPI_STATUS AcpiOsCreateSemaphore(UINT32 MaxUnits, */ ACPI_STATUS AcpiOsDeleteSemaphore(ACPI_HANDLE Handle) { - sem_t *sem = (sem_t *)Handle; + sem_info *sem = (sem_info *)Handle; + ACPI_STATUS ret = AE_OK; if (!sem) return AE_BAD_PARAMETER; - if (sem_destroy(sem) == -1) - return AE_BAD_PARAMETER; + pthread_mutex_lock(&mutex_lock_sem_table); + if (sem_destroy(&sem->sem) == -1) + ret = AE_BAD_PARAMETER; + sem->used = false; - AcpiOsFree(sem); + pthread_mutex_unlock(&mutex_lock_sem_table); - return AE_OK; + return ret; } @@ -601,7 +565,7 @@ ACPI_STATUS AcpiOsDeleteSemaphore(ACPI_HANDLE Handle) */ ACPI_STATUS AcpiOsWaitSemaphore(ACPI_HANDLE handle, UINT32 Units, UINT16 Timeout) { - sem_t *sem = (sem_t *)handle; + sem_info *sem = (sem_info *)handle; struct timespec tm; if (!handle) @@ -612,22 +576,26 @@ ACPI_STATUS AcpiOsWaitSemaphore(ACPI_HANDLE handle, UINT32 Units, UINT16 Timeout switch (Timeout) { case 0: - if (sem_trywait(sem) < 0) + if (sem_trywait(&sem->sem)) return AE_TIME; break; + case ACPI_WAIT_FOREVER: - if (sem_wait(sem)) + if (sem_wait(&sem->sem)) return AE_TIME; break; default: tm.tv_sec = Timeout / 1000; tm.tv_nsec = (Timeout - (tm.tv_sec * 1000)) * 1000000; - if (sem_timedwait(sem, &tm)) + if (sem_timedwait(&sem->sem, &tm)) return AE_TIME; break; } - hash_sem_inc_count(sem); + + pthread_mutex_lock(&mutex_lock_sem_table); + sem->count++; + pthread_mutex_unlock(&mutex_lock_sem_table); return AE_OK; } @@ -639,15 +607,17 @@ ACPI_STATUS AcpiOsWaitSemaphore(ACPI_HANDLE handle, UINT32 Units, UINT16 Timeout */ ACPI_STATUS AcpiOsSignalSemaphore(ACPI_HANDLE handle, UINT32 Units) { - sem_t *sem = (sem_t *)handle; + sem_info *sem = (sem_info *)handle; if (!handle) return AE_BAD_PARAMETER; - if (sem_post(sem) < 0) + if (sem_post(&sem->sem) < 0) return AE_LIMIT; - hash_sem_dec_count(sem); + pthread_mutex_lock(&mutex_lock_sem_table); + sem->count--; + pthread_mutex_unlock(&mutex_lock_sem_table); return AE_OK; } @@ -919,7 +889,7 @@ int fwts_acpica_init(fwts_framework *fw) if (fwts_acpica_init_called) return FWTS_ERROR; - pthread_mutex_init(&mutex_lock_count, NULL); + pthread_mutex_init(&mutex_lock_sem_table, NULL); pthread_mutex_init(&mutex_thread_info, NULL); fwts_acpica_fw = fw; @@ -1108,7 +1078,7 @@ int fwts_acpica_deinit(void) return FWTS_ERROR; AcpiTerminate(); - pthread_mutex_destroy(&mutex_lock_count); + pthread_mutex_destroy(&mutex_lock_sem_table); pthread_mutex_destroy(&mutex_thread_info); FWTS_ACPICA_FREE(fwts_acpica_XSDT);