/* * pte_cancellable_wait.c * * Description: * * -------------------------------------------------------------------------- * * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems * Copyright(C) 2008 Jason Schmidlapp * * Contact Email: jschmidlapp@users.sourceforge.net * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library in the file COPYING.LIB; * if not, write to the Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifndef _GENERIC_OS_SUPPORT_H_ #define _GENERIC_OS_SUPPORT_H_ #ifdef __cplusplus extern "C" { #endif // __cplusplus /** @name Misc */ //@{ typedef enum pte_osResult { /** Operation completed successfully */ PTE_OS_OK = 0, /** Operation failed because there insufficient resources */ PTE_OS_NO_RESOURCES, /** Operation failed due to a general failure */ PTE_OS_GENERAL_FAILURE, /** Operation did not complete because a user specified timeout expired. */ PTE_OS_TIMEOUT, /** The operation was interrupted before it could complete. */ PTE_OS_INTERRUPTED, /** An invalid parameter was specified */ PTE_OS_INVALID_PARAM } pte_osResult; /** * Provides a hook for the OSAL to implement any OS specific initialization. This is guaranteed to be * called before any other OSAL function. */ pte_osResult pte_osInit(void); //@} /** @name Mutexes */ //@{ /** * Creates a mutex * * @param pHandle Set to the handle of the newly created mutex. * * @return PTE_OS_OK - Mutex successfully created * @return PTE_OS_NO_RESOURCESs - Insufficient resources to create mutex */ pte_osResult pte_osMutexCreate(pte_osMutexHandle *pHandle); /** * Deletes a mutex and frees any associated resources. * * @param handle Handle of mutex to delete. * * @return PTE_OS_OK - Mutex successfully deleted. */ pte_osResult pte_osMutexDelete(pte_osMutexHandle handle); /** * Locks the mutex * * @param handle Handle of mutex to lock. * * @return PTE_OS_OK - Mutex successfully locked. */ pte_osResult pte_osMutexLock(pte_osMutexHandle handle); /** * Locks the mutex, returning after @p timeoutMsecs if the resources is not * available. Can be used for polling mutex by using @p timeoutMsecs of zero. * * @param handle Handle of mutex to lock. * @param timeoutMsecs Number of milliseconds to wait for resource before returning. * * @return PTE_OS_OK - Mutex successfully locked. * @return PTE_OS_TIMEOUT - Timeout expired before lock was obtained. */ pte_osResult pte_osMutexTimedLock(pte_osMutexHandle handle, unsigned int timeoutMsecs); /** * Unlocks the mutex * * @param handle Handle of mutex to unlock * * @return PTE_OS_OK - Mutex successfully unlocked. */ pte_osResult pte_osMutexUnlock(pte_osMutexHandle handle); //@} /** @name Threads */ //@{ typedef int (*pte_osThreadEntryPoint)(void *params); /** * Creates a new thread. The thread must be started in a suspended state - it will be * explicitly started when pte_osThreadStart() is called. * * @param entryPoint Entry point to the new thread. * @param stackSize The initial stack size, in bytes. Note that this can be considered a minimum - * for instance if the OS requires a larger stack space than what the caller specified. * @param initialPriority The priority that the new thread should be initially set to. * @param argv Parameter to pass to the new thread. * @param ppte_osThreadHandle set to the handle of the new thread. * * @return PTE_OS_OK - New thread successfully created. * @return PTE_OS_NO_RESOURCESs - Insufficient resources to create thread */ pte_osResult pte_osThreadCreate(pte_osThreadEntryPoint entryPoint, int stackSize, int initialPriority, void *argv, pte_osThreadHandle* ppte_osThreadHandle); /** * Starts executing the specified thread. * * @param osThreadHandle handle of the thread to start. * * @return PTE_OS_OK - thread successfully started. */ pte_osResult pte_osThreadStart(pte_osThreadHandle osThreadHandle); /** * Causes the current thread to stop executing. * * @return Never returns (thread terminated) */ void pte_osThreadExit(); /** * Waits for the specified thread to end. If the thread has already terminated, this returns * immediately. * * @param threadHandle Handle fo thread to wait for. * * @return PTE_OS_OK - specified thread terminated. */ pte_osResult pte_osThreadWaitForEnd(pte_osThreadHandle threadHandle); /** * Returns the handle of the currently executing thread. */ pte_osThreadHandle pte_osThreadGetHandle(void); /** * Returns the priority of the specified thread. */ int pte_osThreadGetPriority(pte_osThreadHandle threadHandle); /** * Sets the priority of the specified thread. * * @return PTE_OS_OK - thread priority successfully set */ pte_osResult pte_osThreadSetPriority(pte_osThreadHandle threadHandle, int newPriority); /** * Frees resources associated with the specified thread. This is called after the thread has terminated * and is no longer needed (e.g. after pthread_join returns). This call will always be made * from a different context than that of the target thread. */ pte_osResult pte_osThreadDelete(pte_osThreadHandle handle); /** * Frees resources associated with the specified thread and then causes the thread to exit. * This is called after the thread has terminated and is no longer needed (e.g. after * pthread_join returns). This call will always be made from the context of the target thread. */ pte_osResult pte_osThreadExitAndDelete(pte_osThreadHandle handle); /** * Cancels the specified thread. This should cause pte_osSemaphoreCancellablePend() and for pte_osThreadCheckCancel() * to return @p PTE_OS_INTERRUPTED. * * @param threadHandle handle to the thread to cancel. * * @return Thread successfully canceled. */ pte_osResult pte_osThreadCancel(pte_osThreadHandle threadHandle); /** * Check if pte_osThreadCancel() has been called on the specified thread. * * @param threadHandle handle of thread to check the state of. * * @return PTE_OS_OK - Thread has not been cancelled * @return PTE_OS_INTERRUPTED - Thread has been cancelled. */ pte_osResult pte_osThreadCheckCancel(pte_osThreadHandle threadHandle); /** * Causes the current thread to sleep for the specified number of milliseconds. */ void pte_osThreadSleep(unsigned int msecs); /** * Returns the maximum allowable priority */ int pte_osThreadGetMaxPriority(); /** * Returns the minimum allowable priority */ int pte_osThreadGetMinPriority(); /** * Returns the priority that should be used if the caller to pthread_create doesn't * explicitly set one. */ int pte_osThreadGetDefaultPriority(); //@} /** @name Semaphores */ //@{ /** * Creates a semaphore * * @param initialValue Initial value of the semaphore * @param pHandle Set to the handle of the newly created semaphore. * * @return PTE_OS_OK - Semaphore successfully created * @return PTE_OS_NO_RESOURCESs - Insufficient resources to create semaphore */ pte_osResult pte_osSemaphoreCreate(int initialValue, pte_osSemaphoreHandle *pHandle); /** * Deletes a semaphore and frees any associated resources. * * @param handle Handle of semaphore to delete. * * @return PTE_OS_OK - Semaphore successfully deleted. */ pte_osResult pte_osSemaphoreDelete(pte_osSemaphoreHandle handle); /** * Posts to the semaphore * * @param handle Semaphore to release * @param count Amount to increment the semaphore by. * * @return PTE_OS_OK - semaphore successfully released. */ pte_osResult pte_osSemaphorePost(pte_osSemaphoreHandle handle, int count); /** * Acquire a semaphore, returning after @p timeoutMsecs if the semaphore is not * available. Can be used for polling a semaphore by using @p timeoutMsecs of zero. * * @param handle Handle of semaphore to acquire. * @param pTimeout Pointer to the number of milliseconds to wait to acquire the semaphore * before returning. If set to NULL, wait forever. * * @return PTE_OS_OK - Semaphore successfully acquired. * @return PTE_OS_TIMEOUT - Timeout expired before semaphore was obtained. */ pte_osResult pte_osSemaphorePend(pte_osSemaphoreHandle handle, unsigned int *pTimeout); /** * Acquire a semaphore, returning after @p timeoutMsecs if the semaphore is not * available. Can be used for polling a semaphore by using @p timeoutMsecs of zero. * Call must return immediately if pte_osThreadCancel() is called on the thread waiting for * the semaphore. * * @param handle Handle of semaphore to acquire. * @param pTimeout Pointer to the number of milliseconds to wait to acquire the semaphore * before returning. If set to NULL, wait forever. * * @return PTE_OS_OK - Semaphore successfully acquired. * @return PTE_OS_TIMEOUT - Timeout expired before semaphore was obtained. */ pte_osResult pte_osSemaphoreCancellablePend(pte_osSemaphoreHandle handle, unsigned int *pTimeout); //@} /** @name Thread Local Storage */ //@{ /** * Sets the thread specific value for the specified key for the * currently executing thread. * * @param index The TLS key for the value. * @param value The value to save */ pte_osResult pte_osTlsSetValue(unsigned int key, void * value); /** * Retrieves the thread specific value for the specified key for * the currently executing thread. If a value has not been set * for this key, NULL should be returned (i.e. TLS values default * to NULL). * * @param index The TLS key for the value. * * @return The value associated with @p key for the current thread. */ void * pte_osTlsGetValue(unsigned int key); /** * Initializes the OS TLS support. This is called by the PTE library * prior to performing ANY TLS operation. */ void pte_osTlsInit(void); /** * Allocates a new TLS key. * * @param pKey On success will be set to the newly allocated key. * * @return PTE_OS_OK - TLS key successfully allocated. * @return PTE_OS_NO_RESOURCESs - Insufficient resources to allocate key (e.g. * maximum number of keys reached). */ pte_osResult pte_osTlsAlloc(unsigned int *pKey); /** * Frees the specified TLS key. * * @param index TLS key to free * * @return PTE_OS_OK - TLS key was successfully freed. */ pte_osResult pte_osTlsFree(unsigned int key); //@} /** @name Atomic operations */ //@{ /** * Sets the target to the specified value as an atomic operation. * * \code * origVal = *ptarg * *ptarg = val * return origVal * \endcode * * @param pTarg Pointer to the value to be exchanged. * @param val Value to be exchanged * * @return original value of destination */ int pte_osAtomicExchange(int *pTarg, int val); /** * Performs an atomic compare-and-exchange oepration on the specified * value. That is: * * \code * origVal = *pdest * if (*pdest == comp) * then *pdest = exchange * return origVal * \endcode * * @param pdest Pointer to the destination value. * @param exchange Exchange value (value to set destination to if destination == comparand) * @param comp The value to compare to destination. * * @return Original value of destination */ int pte_osAtomicCompareExchange(int *pdest, int exchange, int comp); /** * Adds the value to target as an atomic operation * * \code * origVal = *pdest * *pAddend += value * return origVal * \endcode * * @param pdest Pointer to the variable to be updated. * @param value Value to be added to the variable. * * @return Original value of destination */ int pte_osAtomicExchangeAdd(int volatile* pdest, int value); /** * Decrements the destination. * * \code * origVal = *pdest * *pdest++ * return origVal * \endcode * * @param pdest Destination value to decrement * * @return Original destination value */ int pte_osAtomicDecrement(int *pdest); /** * Increments the destination value * * \code * origVal = *pdest; * *pdest++; * return origVal; */ int pte_osAtomicIncrement(int *pdest); //@} struct timeb; int ftime(struct timeb *tb); #ifdef __cplusplus } #endif // __cplusplus #endif // _OS_SUPPORT_H_