/* * Copyright (c) 2001-2003 Swedish Institute of Computer Science. * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * * This file is part of the bluedroid stack. * * Author: Adam Dunkels * */ #include "osi_arch.h" /** Create a new mutex * @param mutex pointer to the mutex to create * @return a new mutex */ int osi_mutex_new(osi_mutex_t *pxMutex) { int xReturn = -1; *pxMutex = xSemaphoreCreateMutex(); if (*pxMutex != NULL) { xReturn = 0; } //LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("osi_mutex_new: m=%p\n", *pxMutex)); return xReturn; } /** Lock a mutex * @param mutex the mutex to lock */ void osi_mutex_lock(osi_mutex_t *pxMutex) { while (xSemaphoreTake(*pxMutex, portMAX_DELAY) != pdPASS); } int osi_mutex_trylock(osi_mutex_t *pxMutex) { if (xSemaphoreTake(*pxMutex, 0) == pdPASS) { return 0; } else { return -1; } } /** Unlock a mutex * @param mutex the mutex to unlock */ void osi_mutex_unlock(osi_mutex_t *pxMutex) { xSemaphoreGive(*pxMutex); } /** Delete a semaphore * @param mutex the mutex to delete */ void osi_mutex_free(osi_mutex_t *pxMutex) { //LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("osi_mutex_free: m=%p\n", *pxMutex)); vQueueDelete(*pxMutex); } /*-----------------------------------------------------------------------------------*/ // Creates and returns a new semaphore. The "init_count" argument specifies // the initial state of the semaphore, "max_count" specifies the maximum value // that can be reached. int osi_sem_new(osi_sem_t *sem, uint32_t max_count, uint32_t init_count) { int xReturn = -1; if (sem) { *sem = xSemaphoreCreateCounting(max_count, init_count); if ((*sem) != NULL) { xReturn = 0; } } return xReturn; } /*-----------------------------------------------------------------------------------*/ // Signals a semaphore void osi_sem_signal(osi_sem_t *sem) { xSemaphoreGive(*sem); } /*-----------------------------------------------------------------------------------*/ /* Blocks the thread while waiting for the semaphore to be signaled. If the "timeout" argument is non-zero, the thread should only be blocked for the specified time (measured in milliseconds). If the timeout argument is non-zero, the return value is the number of milliseconds spent waiting for the semaphore to be signaled. If the semaphore wasn't signaled within the specified time, the return value is OSI_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore (i.e., it was already signaled), the function may return zero. Notice that lwIP implements a function with a similar name, osi_sem_wait(), that uses the osi_arch_sem_wait() function. */ uint32_t osi_sem_wait(osi_sem_t *sem, uint32_t timeout) { portTickType StartTime, EndTime, Elapsed; unsigned long ulReturn; StartTime = xTaskGetTickCount(); if (timeout != 0) { if (xSemaphoreTake(*sem, timeout / portTICK_PERIOD_MS) == pdTRUE) { EndTime = xTaskGetTickCount(); Elapsed = (EndTime - StartTime) * portTICK_PERIOD_MS; if (Elapsed == 0) { Elapsed = 1; } ulReturn = Elapsed; } else { ulReturn = OSI_ARCH_TIMEOUT; } } else { // must block without a timeout while (xSemaphoreTake(*sem, portMAX_DELAY) != pdTRUE); EndTime = xTaskGetTickCount(); Elapsed = (EndTime - StartTime) * portTICK_PERIOD_MS; if (Elapsed == 0) { Elapsed = 1; } ulReturn = Elapsed; } return ulReturn ; // return time blocked } /*-----------------------------------------------------------------------------------*/ // Deallocates a semaphore void osi_sem_free(osi_sem_t *sem) { vSemaphoreDelete(*sem); } /*-----------------------------------------------------------------------------------*/ // Initialize osi arch void osi_arch_init(void) { } /*-----------------------------------------------------------------------------------*/ uint32_t osi_now(void) { return xTaskGetTickCount(); } void osi_delay_ms(uint32_t ms) { vTaskDelay(ms / portTICK_PERIOD_MS); }