threadutil: Doxygenation and compiler warnings.

(cherry picked from commit 7c524df1d91684abbfe710c606a69622de0dbd91)
This commit is contained in:
Marcelo Roberto Jimenez 2010-11-16 00:17:44 -02:00
parent 297d2ae877
commit 18f80bd778
8 changed files with 1053 additions and 1875 deletions

View File

@ -29,118 +29,99 @@
* *
******************************************************************************/ ******************************************************************************/
#ifndef FREE_LIST_H #ifndef FREE_LIST_H
#define FREE_LIST_H #define FREE_LIST_H
/*! /*!
* \file * \file
*/ */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#include "ithread.h" #include "ithread.h"
#include <errno.h> #include <errno.h>
/**************************************************************************** /*!
* Name: FreeListNode * Free list node. points to next free item.
* * Memory for node is borrowed from allocated items.
* Description: * \internal
* free list node. points to next free item. */
* memory for node is borrowed from allocated items.
* Internal Use Only.
*****************************************************************************/
typedef struct FREELISTNODE typedef struct FREELISTNODE
{ {
struct FREELISTNODE *next; struct FREELISTNODE *next;
} FreeListNode; } FreeListNode;
/*!
/**************************************************************************** * Stores head and size of free list, as well as mutex for protection.
* Name: FreeList * \internal
* */
* Description:
* Stores head and size of free list, as well as mutex for protection.
* Internal Use Only.
*****************************************************************************/
typedef struct FREELIST typedef struct FREELIST
{ {
FreeListNode *head; FreeListNode *head;
size_t element_size; size_t element_size;
int maxFreeListLength; int maxFreeListLength;
int freeListLength; int freeListLength;
} FreeList;
}FreeList;
/**************************************************************************** /*!
* Function: FreeListInit * \brief Initializes Free List.
* *
* Description: * Must be called first and only once for FreeList.
* Initializes Free List. Must be called first.
* And only once for FreeList.
* Parameters:
* free_list - must be valid, non null, pointer to a linked list.
* size_t - size of elements to store in free list
* maxFreeListSize - max size that the free list can grow to
* before returning memory to O.S.
* Returns:
* 0 on success. Nonzero on failure.
* Always returns 0.
*****************************************************************************/
int FreeListInit(FreeList *free_list,
size_t elementSize,
int maxFreeListSize);
/****************************************************************************
* Function: FreeListAlloc
* *
* Description: * \return:
* Allocates chunk of set size. * \li \c 0 on success.
* If a free item is available in the list, returnes the stored item. * \li \c EINVAL on failure.
* Otherwise calls the O.S. to allocate memory. */
* Parameters: int FreeListInit(
* free_list - must be valid, non null, pointer to a linked list. /*! Must be valid, non null, pointer to a linked list. */
* Returns: FreeList *free_list,
* Non NULL on success. NULL on failure. /*! Size of elements to store in free list. */
*****************************************************************************/ size_t elementSize,
void * FreeListAlloc (FreeList *free_list); /*! Max size that the free list can grow to before returning
* memory to O.S. */
int maxFreeListLength);
/**************************************************************************** /*!
* Function: FreeListFree * \brief Allocates chunk of set size.
* *
* Description: * If a free item is available in the list, returnes the stored item,
* Returns an item to the Free List. * otherwise calls the O.S. to allocate memory.
* If the free list is smaller than the max size than
* adds the item to the free list.
* Otherwise returns the item to the O.S.
* Parameters:
* free_list - must be valid, non null, pointer to a linked list.
* Returns:
* 0 on success. Nonzero on failure.
* Always returns 0.
*****************************************************************************/
int FreeListFree (FreeList *free_list,void * element);
/****************************************************************************
* Function: FreeListDestroy
* *
* Description: * \return Non NULL on success. NULL on failure.
* Releases the resources stored with the free list. */
* Parameters: void *FreeListAlloc(
* free_list - must be valid, non null, pointer to a linked list. /*! Must be valid, non null, pointer to a linked list. */
* Returns: FreeList *free_list);
* 0 on success. Nonzero on failure.
* Always returns 0.
*****************************************************************************/
int FreeListDestroy (FreeList *free_list);
/*!
* \brief Returns an item to the Free List.
*
* If the free list is smaller than the max size then adds the item to the
* free list, otherwise returns the item to the O.S.
*
* \return:
* \li \c 0 on success.
* \li \c EINVAL on failure.
*/
int FreeListFree(
/*! Must be valid, non null, pointer to a free list. */
FreeList *free_list,
/*! Must be a pointer allocated by FreeListAlloc. */
void *element);
/*!
* \brief Releases the resources stored with the free list.
*
* \return:
* \li \c 0 on success.
* \li \c EINVAL on failure.
*/
int FreeListDestroy(
/*! Must be valid, non null, pointer to a linked list. */
FreeList *free_list);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -29,323 +29,257 @@
* *
******************************************************************************/ ******************************************************************************/
#ifndef LINKED_LIST_H #ifndef LINKED_LIST_H
#define LINKED_LIST_H #define LINKED_LIST_H
/*! /*!
* \file * \file
*/ */
#include "FreeList.h" #include "FreeList.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#define EOUTOFMEM (-7 & 1<<29) #define EOUTOFMEM (-7 & 1<<29)
#define FREELISTSIZE 100 #define FREELISTSIZE 100
#define LIST_SUCCESS 1 #define LIST_SUCCESS 1
#define LIST_FAIL 0 #define LIST_FAIL 0
/*! Function for freeing list items. */
/****************************************************************************
* Name: free_routine
*
* Description:
* Function for freeing list items
*****************************************************************************/
typedef void (*free_function)(void *arg); typedef void (*free_function)(void *arg);
/*! Function for comparing list items. Returns 1 if itemA==itemB */
/****************************************************************************
* Name: cmp_routine
*
* Description:
* Function for comparing list items
* Returns 1 if itemA==itemB
*****************************************************************************/
typedef int (*cmp_routine)(void *itemA,void *itemB); typedef int (*cmp_routine)(void *itemA,void *itemB);
/*! Linked list node. Stores generic item and pointers to next and prev.
/**************************************************************************** * \internal
* Name: ListNode */
*
* Description:
* linked list node. stores generic item and pointers to next and prev.
* Internal Use Only.
*****************************************************************************/
typedef struct LISTNODE typedef struct LISTNODE
{ {
struct LISTNODE *prev; struct LISTNODE *prev;
struct LISTNODE *next; struct LISTNODE *next;
void *item; void *item;
} ListNode; } ListNode;
/*!
/**************************************************************************** * Linked list (no protection).
* Name: LinkedList
* *
* Description: * Because this is for internal use, parameters are NOT checked for validity.
* linked list (no protection). Internal Use Only. * The first item of the list is stored at node: head->next
* Because this is for internal use, parameters are NOT checked for * The last item of the list is stored at node: tail->prev
* validity. * If head->next=tail, then list is empty.
* The first item of the list is stored at node: head->next * To iterate through the list:
* The last item of the list is stored at node: tail->prev
* If head->next=tail, then list is empty.
* To iterate through the list:
* *
* LinkedList g; * LinkedList g;
* ListNode *temp = NULL; * ListNode *temp = NULL;
* for (temp = ListHead(g);temp!=NULL;temp = ListNext(g,temp)) * for (temp = ListHead(g);temp!=NULL;temp = ListNext(g,temp)) {
* { * }
* }
* *
*****************************************************************************/ * \internal
*/
typedef struct LINKEDLIST typedef struct LINKEDLIST
{ {
ListNode head; /* head, first item is stored at: head->next */ /*! head, first item is stored at: head->next */
ListNode tail; /* tail, last item is stored at: tail->prev */ ListNode head;
long size; /* size of list */ /*! tail, last item is stored at: tail->prev */
FreeList freeNodeList; /* free list to use */ ListNode tail;
free_function free_func; /* free function to use */ /*! size of list */
cmp_routine cmp_func; /* compare function to use */ long size;
/*! free list to use */
FreeList freeNodeList;
/*! free function to use */
free_function free_func;
/*! compare function to use */
cmp_routine cmp_func;
} LinkedList; } LinkedList;
/*!
* \brief Initializes LinkedList. Must be called first and only once for List.
*
* \return
* \li \c 0 on success.
* \li \c EOUTOFMEM on failure.
*/
int ListInit(
/*! Must be valid, non null, pointer to a linked list. */
LinkedList *list,
/*! Function used to compare items. (May be NULL). */
cmp_routine cmp_func,
/*! Function used to free items. (May be NULL). */
free_function free_func);
/**************************************************************************** /*!
* Function: ListInit * \brief Adds a node to the head of the list. Node gets immediately after
* list head.
* *
* Description:
* Initializes LinkedList. Must be called first.
* And only once for List.
* Parameters:
* list - must be valid, non null, pointer to a linked list.
* cmp_func - function used to compare items. (May be NULL)
* free_func - function used to free items. (May be NULL)
* Returns:
* 0 on success, EOUTOFMEM on failure.
*****************************************************************************/
int ListInit(LinkedList *list,cmp_routine cmp_func, free_function free_func);
/****************************************************************************
* Function: ListAddHead
*
* Description:
* Adds a node to the head of the list.
* Node gets immediately after list.head.
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
* void * item - item to be added
* Returns:
* The pointer to the ListNode on success, NULL on failure.
* Precondition: * Precondition:
* The list has been initialized. * The list has been initialized.
*****************************************************************************/
ListNode *ListAddHead(LinkedList *list, void *item);
/****************************************************************************
* Function: ListAddTail
* *
* Description: * \return The pointer to the ListNode on success, NULL on failure.
* Adds a node to the tail of the list. */
* Node gets added immediately before list.tail. ListNode *ListAddHead(
* Parameters: /*! Must be valid, non null, pointer to a linked list. */
* LinkedList *list - must be valid, non null, pointer to a linked list. LinkedList *list,
* void * item - item to be added /*! Item to be added. */
* Returns: void *item);
* The pointer to the ListNode on success, NULL on failure.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode *ListAddTail(LinkedList *list, void *item);
/*!
/**************************************************************************** * \brief Adds a node to the tail of the list. Node gets added immediately
* Function: ListAddAfter * before list.tail.
* *
* Description: * Precondition: The list has been initialized.
* Adds a node after the specified node.
* Node gets added immediately after bnode.
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
* void * item - item to be added
* ListNode * bnode - node to add after
* Returns:
* The pointer to the ListNode on success, NULL on failure.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode *ListAddAfter(LinkedList *list, void *item, ListNode *bnode);
/****************************************************************************
* Function: ListAddBefore
* *
* Description: * \return The pointer to the ListNode on success, NULL on failure.
* Adds a node before the specified node. */
* Node gets added immediately before anode. ListNode *ListAddTail(
* Parameters: /*! Must be valid, non null, pointer to a linked list. */
* LinkedList *list - must be valid, non null, pointer to a linked list. LinkedList *list,
* ListNode * anode - node to add the in front of. /*! Item to be added. */
* void * item - item to be added void *item);
* Returns:
* The pointer to the ListNode on success, NULL on failure.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode *ListAddBefore(LinkedList *list,void *item, ListNode *anode);
/*!
/**************************************************************************** * \brief Adds a node after the specified node. Node gets added immediately
* Function: ListDelNode * after bnode.
* *
* Description: * Precondition: The list has been initialized.
* Removes a node from the list
* The memory for the node is freed.
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
* ListNode *dnode - done to delete.
* freeItem - if !0 then item is freed using free function.
* if 0 (or free function is NULL) then item is not freed
* Returns:
* The pointer to the item stored in the node or NULL if the item is freed.
* Precondition:
* The list has been initialized.
*****************************************************************************/
void *ListDelNode(LinkedList *list,ListNode *dnode, int freeItem);
/****************************************************************************
* Function: ListDestroy
* *
* Description: * \return The pointer to the ListNode on success, NULL on failure.
* Removes all memory associated with list nodes. */
* Does not free LinkedList *list. ListNode *ListAddAfter(
/*! Must be valid, non null, pointer to a linked list. */
LinkedList *list,
/*! Item to be added. */
void *item,
/*! Node to add after. */
ListNode *bnode);
/*!
* \brief Adds a node before the specified node. Node gets added immediately
* before anode.
*
* Precondition: The list has been initialized.
*
* \return The pointer to the ListNode on success, NULL on failure.
*/
ListNode *ListAddBefore(
/*! Must be valid, non null, pointer to a linked list. */
LinkedList *list,
/*! Item to be added. */
void *item,
/*! Node to add in front of. */
ListNode *anode);
/*!
* \brief Removes a node from the list. The memory for the node is freed.
*
* Precondition: The list has been initialized.
*
* \return The pointer to the item stored in the node or NULL if the item
* is freed.
*/
void *ListDelNode(
/*! Must be valid, non null, pointer to a linked list. */
LinkedList *list,
/*! Node to delete. */
ListNode *dnode,
/*! if !0 then item is freed using free function. If 0 (or free
* function is NULL) then item is not freed. */
int freeItem);
/*!
* \brief Removes all memory associated with list nodes. Does not free
* LinkedList *list.
*
* Precondition: The list has been initialized.
*
* \return 0 on success, EINVAL on failure.
*/
int ListDestroy(
/*! Must be valid, non null, pointer to a linked list. */
LinkedList *list,
/*! if !0 then item is freed using free function. If 0 (or free
* function is NULL) then item is not freed. */
int freeItem);
/*!
* \brief Returns the head of the list.
* *
* Parameters: * Precondition: The list has been initialized.
* LinkedList *list - must be valid, non null, pointer to a linked list.
* freeItem - if !0 then items are freed using the free_function.
* if 0 (or free function is NULL) then items are not freed.
* Returns:
* 0 on success. Always returns 0.
* Precondition:
* The list has been initialized.
*****************************************************************************/
int ListDestroy(LinkedList *list, int freeItem);
/****************************************************************************
* Function: ListHead
* *
* Description: * \return The head of the list. NULL if list is empty.
* Returns the head of the list. */
ListNode *ListHead(
/*! Must be valid, non null, pointer to a linked list. */
LinkedList *list);
/*!
* \brief Returns the tail of the list.
* *
* Parameters: * Precondition: The list has been initialized.
* LinkedList *list - must be valid, non null, pointer to a linked list.
*
* Returns:
* The head of the list. NULL if list is empty.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode* ListHead(LinkedList *list);
/****************************************************************************
* Function: ListTail
* *
* Description: * \return The tail of the list. NULL if list is empty.
* Returns the tail of the list. */
ListNode *ListTail(
/*! Must be valid, non null, pointer to a linked list. */
LinkedList *list);
/*!
* \brief Returns the next item in the list.
* *
* Parameters: * Precondition: The list has been initialized.
* LinkedList *list - must be valid, non null, pointer to a linked list.
*
* Returns:
* The tail of the list. NULL if list is empty.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode* ListTail(LinkedList *list);
/****************************************************************************
* Function: ListNext
* *
* Description: * \return The next item in the list. NULL if there are no more items in list.
* Returns the next item in the list. */
ListNode *ListNext(
/*! Must be valid, non null, pointer to a linked list. */
LinkedList *list,
/*! Node from the list. */
ListNode *node);
/*!
* \brief Returns the previous item in the list.
* *
* Parameters: * Precondition: The list has been initialized.
* LinkedList *list - must be valid, non null, pointer to a linked list.
*
* Returns:
* The next item in the list. NULL if there are no more items in list.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode* ListNext(LinkedList *list, ListNode * node);
/****************************************************************************
* Function: ListPrev
* *
* Description: * \return The previous item in the list. NULL if there are no more items in list.
* Returns the previous item in the list. */
* ListNode *ListPrev(
* Parameters: /*! Must be valid, non null, pointer to a linked list. */
* LinkedList *list - must be valid, non null, pointer to a linked list. LinkedList *list,
* /*! Node from the list. */
* Returns: ListNode *node);
* The previous item in the list. NULL if there are no more items in list.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode* ListPrev(LinkedList *list, ListNode * node);
/*!
/**************************************************************************** * \brief Finds the specified item in the list.
* Function: ListFind
* *
* Description: * Uses the compare function specified in ListInit. If compare function
* Finds the specified item in the list. * is NULL then compares items as pointers.
* Uses the compare function specified in ListInit. If compare function
* is NULL then compares items as pointers.
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
* ListNode *start - the node to start from, NULL if to start from
* beginning.
* void * item - the item to search for.
* Returns:
* The node containing the item. NULL if no node contains the item.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode* ListFind(LinkedList *list, ListNode *start, void * item);
/****************************************************************************
* Function: ListSize
* *
* Description: * Precondition: The list has been initialized.
* Returns the size of the list. *
* Parameters: * \return The node containing the item. NULL if no node contains the item.
* LinkedList *list - must be valid, non null, pointer to a linked list. */
ListNode* ListFind(
* Returns: /*! Must be valid, non null, pointer to a linked list. */
* The number of items in the list. LinkedList *list,
* Precondition: /*! The node to start from, NULL if to start from beginning. */
* The list has been initialized. ListNode *start,
*****************************************************************************/ /*! The item to search for. */
int ListSize(LinkedList* list); void *item);
/*!
* \brief Returns the size of the list.
*
* Precondition: The list has been initialized.
*
* \return The number of items in the list.
*/
long ListSize(
/*! Must be valid, non null, pointer to a linked list. */
LinkedList* list);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -29,26 +29,21 @@
* *
******************************************************************************/ ******************************************************************************/
#ifndef THREADPOOL_H #ifndef THREADPOOL_H
#define THREADPOOL_H #define THREADPOOL_H
/*! /*!
* \file * \file
*/ */
#include "FreeList.h" #include "FreeList.h"
#include "ithread.h" #include "ithread.h"
#include "LinkedList.h" #include "LinkedList.h"
#include "UpnpInet.h" #include "UpnpInet.h"
#include "UpnpGlobal.h" /* for UPNP_INLINE, EXPORT_SPEC */ #include "UpnpGlobal.h" /* for UPNP_INLINE, EXPORT_SPEC */
#include <errno.h> #include <errno.h>
#ifdef WIN32 #ifdef WIN32
#include <time.h> #include <time.h>
struct timezone struct timezone
@ -63,82 +58,63 @@
#if defined(__OSX__) || defined(__APPLE__) || defined(__NetBSD__) #if defined(__OSX__) || defined(__APPLE__) || defined(__NetBSD__)
#include <sys/resource.h> /* for setpriority() */ #include <sys/resource.h> /* for setpriority() */
#endif #endif
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/*! Size of job free list */ /*! Size of job free list */
#define JOBFREELISTSIZE 100 #define JOBFREELISTSIZE 100
#define INFINITE_THREADS -1 #define INFINITE_THREADS -1
#define EMAXTHREADS (-8 & 1<<29) #define EMAXTHREADS (-8 & 1<<29)
/*! Invalid Policy */ /*! Invalid Policy */
#define INVALID_POLICY (-9 & 1<<29) #define INVALID_POLICY (-9 & 1<<29)
/*! Invalid JOB Id */ /*! Invalid JOB Id */
#define INVALID_JOB_ID (-2 & 1<<29) #define INVALID_JOB_ID (-2 & 1<<29)
typedef enum duration { typedef enum duration {
SHORT_TERM, SHORT_TERM,
PERSISTENT PERSISTENT
} Duration; } Duration;
typedef enum priority { typedef enum priority {
LOW_PRIORITY, LOW_PRIORITY,
MED_PRIORITY, MED_PRIORITY,
HIGH_PRIORITY HIGH_PRIORITY
} ThreadPriority; } ThreadPriority;
/*! default priority used by TPJobInit */ /*! default priority used by TPJobInit */
#define DEFAULT_PRIORITY MED_PRIORITY #define DEFAULT_PRIORITY MED_PRIORITY
/*! default minimum used by TPAttrInit */ /*! default minimum used by TPAttrInit */
#define DEFAULT_MIN_THREADS 1 #define DEFAULT_MIN_THREADS 1
/*! default max used by TPAttrInit */ /*! default max used by TPAttrInit */
#define DEFAULT_MAX_THREADS 10 #define DEFAULT_MAX_THREADS 10
/*! default stack size used by TPAttrInit */ /*! default stack size used by TPAttrInit */
#define DEFAULT_STACK_SIZE 0 #define DEFAULT_STACK_SIZE 0
/*! default jobs per thread used by TPAttrInit */ /*! default jobs per thread used by TPAttrInit */
#define DEFAULT_JOBS_PER_THREAD 10 #define DEFAULT_JOBS_PER_THREAD 10
/*! default starvation time used by TPAttrInit */ /*! default starvation time used by TPAttrInit */
#define DEFAULT_STARVATION_TIME 500 #define DEFAULT_STARVATION_TIME 500
/*! default idle time used by TPAttrInit */ /*! default idle time used by TPAttrInit */
#define DEFAULT_IDLE_TIME 10 * 1000 #define DEFAULT_IDLE_TIME 10 * 1000
/*! default free routine used TPJobInit */ /*! default free routine used TPJobInit */
#define DEFAULT_FREE_ROUTINE NULL #define DEFAULT_FREE_ROUTINE NULL
/*! default max jobs used TPAttrInit */ /*! default max jobs used TPAttrInit */
#define DEFAULT_MAX_JOBS_TOTAL 100 #define DEFAULT_MAX_JOBS_TOTAL 100
/*! /*!
* \brief Statistics. * \brief Statistics.
* *
@ -146,71 +122,43 @@ typedef enum priority {
*/ */
#define STATS 1 #define STATS 1
#ifdef _DEBUG #ifdef _DEBUG
#define DEBUG 1 #define DEBUG 1
#endif #endif
typedef int PolicyType; typedef int PolicyType;
#define DEFAULT_POLICY SCHED_OTHER #define DEFAULT_POLICY SCHED_OTHER
/*! Function for freeing a thread argument. */
/****************************************************************************
* Name: free_routine
*
* Description:
* Function for freeing a thread argument
*****************************************************************************/
typedef void (*free_routine)(void *arg); typedef void (*free_routine)(void *arg);
/**************************************************************************** /*! Attributes for thread pool. Used to set and change parameters of thread
* Name: ThreadPoolAttr * pool. */
*
* Description:
* Attributes for thread pool. Used to set and change parameters of
* thread pool
*****************************************************************************/
typedef struct THREADPOOLATTR typedef struct THREADPOOLATTR
{ {
/* minThreads, ThreadPool will always maintain at least this many threads */ /*! ThreadPool will always maintain at least this many threads. */
int minThreads; int minThreads;
/*! ThreadPool will never have more than this number of threads. */
/* maxThreads, ThreadPool will never have more than this number of threads */
int maxThreads; int maxThreads;
/*! This is the minimum stack size allocated for each thread. */
/* stackSize (in bytes), this is the minimum stack size allocated for each
* thread */
size_t stackSize; size_t stackSize;
/*! This is the maximum time a thread will
/* maxIdleTime (in milliseconds) this is the maximum time a thread will * remain idle before dying (in milliseconds). */
* remain idle before dying */
int maxIdleTime; int maxIdleTime;
/*! Jobs per thread to maintain. */
/* jobs per thread to maintain */
int jobsPerThread; int jobsPerThread;
/*! Maximum number of jobs that can be queued totally. */
/* maximum number of jobs that can be queued totally. */
int maxJobsTotal; int maxJobsTotal;
/*! the time a low priority or med priority job waits before getting
/* the time a low priority or med priority job waits before getting bumped * bumped up a priority (in milliseconds). */
* up a priority (in milliseconds) */
int starvationTime; int starvationTime;
/*! scheduling policy to use. */
/* scheduling policy to use */
PolicyType schedPolicy; PolicyType schedPolicy;
} ThreadPoolAttr; } ThreadPoolAttr;
/*! Internal ThreadPool Job. */
/****************************************************************************
* Name: ThreadPool
*
* Description:
* Internal ThreadPool Job
*****************************************************************************/
typedef struct THREADPOOLJOB typedef struct THREADPOOLJOB
{ {
start_routine func; start_routine func;
@ -221,13 +169,7 @@ typedef struct THREADPOOLJOB
int jobId; int jobId;
} ThreadPoolJob; } ThreadPoolJob;
/*! Structure to hold statistics. */
/****************************************************************************
* Name: ThreadPoolStats
*
* Description:
* Structure to hold statistics
*****************************************************************************/
typedef struct TPOOLSTATS typedef struct TPOOLSTATS
{ {
double totalTimeHQ; double totalTimeHQ;
@ -251,7 +193,6 @@ typedef struct TPOOLSTATS
int currentJobsMQ; int currentJobsMQ;
} ThreadPoolStats; } ThreadPoolStats;
/*! /*!
* \brief A thread pool similar to the thread pool in the UPnP SDK. * \brief A thread pool similar to the thread pool in the UPnP SDK.
* *
@ -269,374 +210,324 @@ typedef struct TPOOLSTATS
*/ */
typedef struct THREADPOOL typedef struct THREADPOOL
{ {
ithread_mutex_t mutex; /* mutex to protect job qs */ /*! Mutex to protect job qs. */
ithread_cond_t condition; /* condition variable to signal Q */ ithread_mutex_t mutex;
ithread_cond_t start_and_shutdown; /* condition variable for start and stop */ /*! Condition variable to signal Q. */
int lastJobId; /* ids for jobs */ ithread_cond_t condition;
int shutdown; /* whether or not we are shutting down */ /*! Condition variable for start and stop. */
int totalThreads; /* total number of threads */ ithread_cond_t start_and_shutdown;
int busyThreads; /* number of threads that are currently executing jobs */ /*! ids for jobs */
int persistentThreads; /* number of persistent threads */ int lastJobId;
FreeList jobFreeList; /* free list of jobs */ /*! whether or not we are shutting down */
LinkedList lowJobQ; /* low priority job Q */ int shutdown;
LinkedList medJobQ; /* med priority job Q */ /*! total number of threads */
LinkedList highJobQ; /* high priority job Q */ int totalThreads;
ThreadPoolJob *persistentJob; /* persistent job */ /*! number of threads that are currently executing jobs */
ThreadPoolAttr attr; /* thread pool attributes */ int busyThreads;
/*! number of persistent threads */
/* statistics */ int persistentThreads;
/*! free list of jobs */
FreeList jobFreeList;
/*! low priority job Q */
LinkedList lowJobQ;
/*! med priority job Q */
LinkedList medJobQ;
/*! high priority job Q */
LinkedList highJobQ;
/*! persistent job */
ThreadPoolJob *persistentJob;
/*! thread pool attributes */
ThreadPoolAttr attr;
/*! statistics */
ThreadPoolStats stats; ThreadPoolStats stats;
} ThreadPool; } ThreadPool;
/*!
* \brief Initializes and starts ThreadPool. Must be called first and
* only once for ThreadPool.
*
* \return
* \li \c 0 on success.
* \li \c EAGAIN if not enough system resources to create minimum threads.
* \li \c INVALID_POLICY if schedPolicy can't be set.
* \li \c EMAXTHREADS if minimum threads is greater than maximum threads.
*/
int ThreadPoolInit(
/*! Must be valid, non null, pointer to ThreadPool. */
ThreadPool *tp,
/*! Can be null. if not null then attr contains the following fields:
* \li \c minWorkerThreads - minimum number of worker threads thread
* pool will never have less than this number of threads.
* \li \c maxWorkerThreads - maximum number of worker threads thread
* pool will never have more than this number of threads.
* \li \c maxIdleTime - maximum time that a worker thread will spend
* idle. If a worker is idle longer than this time and there are more
* than the min number of workers running, then the worker thread
* exits.
* \li \c jobsPerThread - ratio of jobs to thread to try and maintain
* if a job is scheduled and the number of jobs per thread is greater
* than this number,and if less than the maximum number of workers are
* running then a new thread is started to help out with efficiency.
* \li \c schedPolicy - scheduling policy to try and set (OS dependent).
*/
ThreadPoolAttr *attr);
/**************************************************************************** /*!
* Function: ThreadPoolInit * \brief Adds a persistent job to the thread pool.
* *
* Description: * Job will be run as soon as possible. Call will block until job is scheduled.
* Initializes and starts ThreadPool. Must be called first.
* And only once for ThreadPool.
* Parameters:
* tp - must be valid, non null, pointer to ThreadPool.
* attr - can be null
*
* if not null then attr contains the following fields:
*
* minWorkerThreads - minimum number of worker threads
* thread pool will never have less than this
* number of threads.
* maxWorkerThreads - maximum number of worker threads
* thread pool will never have more than this
* number of threads.
* maxIdleTime - maximum time that a worker thread will spend
* idle. If a worker is idle longer than this
* time and there are more than the min
* number of workers running, than the
* worker thread exits.
* jobsPerThread - ratio of jobs to thread to try and maintain
* if a job is scheduled and the number of jobs per
* thread is greater than this number,and
* if less than the maximum number of
* workers are running then a new thread is
* started to help out with efficiency.
* schedPolicy - scheduling policy to try and set (OS dependent)
* Returns:
* 0 on success, nonzero on failure.
* EAGAIN if not enough system resources to create minimum threads.
* INVALID_POLICY if schedPolicy can't be set
* EMAXTHREADS if minimum threads is greater than maximum threads
*****************************************************************************/
int ThreadPoolInit(ThreadPool *tp, ThreadPoolAttr *attr);
/****************************************************************************
* Function: ThreadPoolAddPersistent
*
* Description:
* Adds a persistent job to the thread pool.
* Job will be run as soon as possible.
* Call will block until job is scheduled.
* Parameters:
* tp - valid thread pool pointer
* ThreadPoolJob - valid thread pool job with the following fields:
*
* func - ThreadFunction to run
* arg - argument to function.
* priority - priority of job.
* *
* Returns: * \return
* 0 on success, nonzero on failure * \li \c 0 on success.
* EOUTOFMEM not enough memory to add job. * \li \c EOUTOFMEM not enough memory to add job.
* EMAXTHREADS not enough threads to add persistent job. * \li \c EMAXTHREADS not enough threads to add persistent job.
*****************************************************************************/ */
int ThreadPoolAddPersistent(ThreadPool*tp, ThreadPoolJob *job, int *jobId); int ThreadPoolAddPersistent(
/*! Valid thread pool pointer. */
ThreadPool*tp,
/*! Valid thread pool job. */
ThreadPoolJob *job,
/*! . */
int *jobId);
/*!
/**************************************************************************** * \brief Gets the current set of attributes associated with the thread pool.
* Function: ThreadPoolGetAttr
* *
* Description: * \return
* Gets the current set of attributes * \li \c 0 on success, nonzero on failure.
* associated with the thread pool. */
* Parameters: int ThreadPoolGetAttr(
* tp - valid thread pool pointer /*! valid thread pool pointer. */
* out - non null pointer to store attributes ThreadPool *tp,
* Returns: /*! non null pointer to store attributes. */
* 0 on success, nonzero on failure ThreadPoolAttr *out);
* Always returns 0.
*****************************************************************************/
int ThreadPoolGetAttr(ThreadPool *tp, ThreadPoolAttr *out);
/*!
/**************************************************************************** * \brief Sets the attributes for the thread pool.
* Function: ThreadPoolSetAttr * Only affects future calculations.
* *
* Description: * \return
* Sets the attributes for the thread pool. * \li \c 0 on success, nonzero on failure.
* Only affects future calculations. * \li \c INVALID_POLICY if policy can not be set.
* Parameters: */
* tp - valid thread pool pointer int ThreadPoolSetAttr(
* attr - pointer to attributes, null sets attributes to default. /*! valid thread pool pointer. */
* Returns: ThreadPool *tp,
* 0 on success, nonzero on failure /*! pointer to attributes, null sets attributes to default. */
* Returns INVALID_POLICY if policy can not be set. ThreadPoolAttr *attr);
*****************************************************************************/
int ThreadPoolSetAttr(ThreadPool *tp, ThreadPoolAttr *attr);
/*!
/**************************************************************************** * \brief Adds a job to the thread pool. Job will be run as soon as possible.
* Function: ThreadPoolAdd
* *
* Description: * \return
* Adds a job to the thread pool. * \li \c 0 on success, nonzero on failure.
* Job will be run as soon as possible. * \li \c EOUTOFMEM if not enough memory to add job.
* Parameters: */
* tp - valid thread pool pointer int ThreadPoolAdd(
* func - ThreadFunction to run /*! valid thread pool pointer. */
* arg - argument to function. ThreadPool*tp,
* priority - priority of job. /*! . */
* poolid - id of job ThreadPoolJob *job,
* free_function - function to use when freeing argument /*! id of job. */
* Returns: int *jobId);
* 0 on success, nonzero on failure
* EOUTOFMEM if not enough memory to add job.
*****************************************************************************/
int ThreadPoolAdd (ThreadPool*tp, ThreadPoolJob *job, int *jobId);
/*!
/**************************************************************************** * \brief Removes a job from the thread pool. Can only remove jobs which
* Function: ThreadPoolRemove * are not currently running.
* *
* Description: * \return
* Removes a job from the thread pool. * \li \c 0 on success, nonzero on failure.
* Can only remove jobs which are not * \li \c INVALID_JOB_ID if job not found.
* currently running. */
* Parameters: int ThreadPoolRemove(
* tp - valid thread pool pointer /*! valid thread pool pointer. */
* jobid - id of job ThreadPool *tp,
* out - space for removed job. /*! id of job. */
* Returns: int jobId,
* 0 on success, nonzero on failure. /*! space for removed job. */
* INVALID_JOB_ID if job not found. ThreadPoolJob *out);
*****************************************************************************/
int ThreadPoolRemove(ThreadPool *tp, int jobId, ThreadPoolJob *out);
/*!
* \brief Shuts the thread pool down. Waits for all threads to finish.
/**************************************************************************** * May block indefinitely if jobs do not exit.
* Function: ThreadPoolShutdown
* *
* Description: * \return 0 on success, nonzero on failure
* Shuts the thread pool down. */
* Waits for all threads to finish. int ThreadPoolShutdown(
* May block indefinitely if jobs do not /*! must be valid tp. */
* exit. ThreadPool *tp);
* Parameters:
* tp - must be valid tp
* Returns:
* 0 on success, nonzero on failure
* Always returns 0.
*****************************************************************************/
int ThreadPoolShutdown(ThreadPool *tp);
/*!
/**************************************************************************** * \brief Initializes thread pool job. Sets the priority to default defined
* Function: TPJobInit * in ThreadPool.h. Sets the free_routine to default defined in ThreadPool.h.
* *
* Description: * \return Always returns 0.
* Initializes thread pool job. */
* Sets the priority to default defined in ThreadPool.h. int TPJobInit(
* Sets the free_routine to default defined in ThreadPool.h /*! must be valid thread pool attributes. */
* Parameters: ThreadPoolJob *job,
* ThreadPoolJob *job - must be valid thread pool attributes. /*! function to run, must be valid. */
* start_routine func - function to run, must be valid start_routine func,
* void * arg - argument to pass to function. /*! argument to pass to function. */
* Returns: void *arg);
* Always returns 0.
*****************************************************************************/
int TPJobInit(ThreadPoolJob *job, start_routine func, void *arg);
/*!
/**************************************************************************** * \brief Sets the max threads for the thread pool attributes.
* Function: TPJobSetPriority
* *
* Description: * \return Always returns 0.
* Sets the max threads for the thread pool attributes. */
* Parameters: int TPJobSetPriority(
* attr - must be valid thread pool attributes. /*! must be valid thread pool attributes. */
* maxThreads - value to set ThreadPoolJob *job,
* Returns: /*! value to set. */
* Always returns 0. ThreadPriority priority);
*****************************************************************************/
int TPJobSetPriority(ThreadPoolJob *job, ThreadPriority priority);
/*!
/**************************************************************************** * \brief Sets the max threads for the thread pool attributes.
* Function: TPJobSetFreeFunction
* *
* Description: * \return Always returns 0.
* Sets the max threads for the thread pool attributes. */
* Parameters: int TPJobSetFreeFunction(
* attr - must be valid thread pool attributes. /*! must be valid thread pool attributes. */
* maxThreads - value to set ThreadPoolJob *job,
* Returns: /*! value to set. */
* Always returns 0. free_routine func);
*****************************************************************************/
int TPJobSetFreeFunction(ThreadPoolJob *job, free_routine func);
/*!
/**************************************************************************** * \brief Initializes thread pool attributes. Sets values to defaults defined
* Function: TPAttrInit * in ThreadPool.h.
* *
* Description: * \return Always returns 0.
* Initializes thread pool attributes. */
* Sets values to defaults defined in ThreadPool.h. int TPAttrInit(
* Parameters: /*! must be valid thread pool attributes. */
* attr - must be valid thread pool attributes. ThreadPoolAttr *attr);
* Returns:
* Always returns 0.
*****************************************************************************/
int TPAttrInit(ThreadPoolAttr *attr);
/*!
/**************************************************************************** * \brief Sets the max threads for the thread pool attributes.
* Function: TPAttrSetMaxThreads
* *
* Description: * \return Always returns 0.
* Sets the max threads for the thread pool attributes. */
* Parameters: int TPAttrSetMaxThreads(
* attr - must be valid thread pool attributes. /*! must be valid thread pool attributes. */
* maxThreads - value to set ThreadPoolAttr *attr,
* Returns: /*! value to set. */
* Always returns 0. int maxThreads);
*****************************************************************************/
int TPAttrSetMaxThreads(ThreadPoolAttr *attr, int maxThreads);
/*!
/**************************************************************************** * \brief Sets the min threads for the thread pool attributes.
* Function: TPAttrSetMinThreads
* *
* Description: * \return Always returns 0.
* Sets the min threads for the thread pool attributes. */
* Parameters: int TPAttrSetMinThreads(
* attr - must be valid thread pool attributes. /*! must be valid thread pool attributes. */
* minThreads - value to set ThreadPoolAttr *attr,
* Returns: /*! value to set. */
* Always returns 0. int minThreads);
*****************************************************************************/
int TPAttrSetMinThreads(ThreadPoolAttr *attr, int minThreads);
/*!
/**************************************************************************** * \brief Sets the stack size for the thread pool attributes.
* Function: TPAttrSetStackSize
* *
* Description: * \return Always returns 0.
* Sets the stack size for the thread pool attributes. */
* Parameters: int TPAttrSetStackSize(
* attr - must be valid thread pool attributes. /*! must be valid thread pool attributes. */
* stackSize - value to set ThreadPoolAttr *attr,
* Returns: /*! value to set. */
* Always returns 0. size_t stackSize);
*****************************************************************************/
int TPAttrSetStackSize(ThreadPoolAttr *attr, size_t stackSize);
/*!
/**************************************************************************** * \brief Sets the idle time for the thread pool attributes.
* Function: TPAttrSetIdleTime
* *
* Description: * \return Always returns 0.
* Sets the idle time for the thread pool attributes. */
* Parameters: int TPAttrSetIdleTime(
* attr - must be valid thread pool attributes. /*! must be valid thread pool attributes. */
* Returns: ThreadPoolAttr *attr,
* Always returns 0. /*! . */
*****************************************************************************/ int idleTime);
int TPAttrSetIdleTime(ThreadPoolAttr *attr, int idleTime);
/*!
/**************************************************************************** * \brief Sets the jobs per thread ratio
* Function: TPAttrSetJobsPerThread
* *
* Description: * \return Always returns 0.
* Sets the jobs per thread ratio */
* Parameters: int TPAttrSetJobsPerThread(
* attr - must be valid thread pool attributes. /*! must be valid thread pool attributes. */
* jobsPerThread - number of jobs per thread to maintain ThreadPoolAttr *attr,
* Returns: /*! number of jobs per thread to maintain. */
* Always returns 0. int jobsPerThread);
*****************************************************************************/
int TPAttrSetJobsPerThread(ThreadPoolAttr *attr, int jobsPerThread);
/*!
/**************************************************************************** * \brief Sets the starvation time for the thread pool attributes.
* Function: TPAttrSetStarvationTime
* *
* Description: * \return Always returns 0.
* Sets the starvation time for the thread pool attributes. */
* Parameters: int TPAttrSetStarvationTime(
* attr - must be valid thread pool attributes. /*! must be valid thread pool attributes. */
* int starvationTime - milliseconds ThreadPoolAttr *attr,
* Returns: /*! milliseconds. */
* Always returns 0. int starvationTime);
*****************************************************************************/
int TPAttrSetStarvationTime(ThreadPoolAttr *attr, int starvationTime);
/*!
/**************************************************************************** * \brief Sets the scheduling policy for the thread pool attributes.
* Function: TPAttrSetSchedPolicy
* *
* Description: * \return Always returns 0.
* Sets the scheduling policy for the thread pool attributes. */
* Parameters: int TPAttrSetSchedPolicy(
* attr - must be valid thread pool attributes. /*! must be valid thread pool attributes. */
* PolicyType schedPolicy - must be a valid policy type. ThreadPoolAttr *attr,
* Returns: /*! must be a valid policy type. */
* Always returns 0. PolicyType schedPolicy);
*****************************************************************************/
int TPAttrSetSchedPolicy(ThreadPoolAttr *attr, PolicyType schedPolicy);
/*!
/**************************************************************************** * \brief Sets the maximum number jobs that can be qeued totally.
* Function: TPAttrSetMaxJobsTotal
* *
* Description: * \return Always returns 0.
* Sets the maximum number jobs that can be qeued totally. */
* Parameters: int TPAttrSetMaxJobsTotal(
* attr - must be valid thread pool attributes. /*! must be valid thread pool attributes. */
* maxJobsTotal - maximum number of jobs ThreadPoolAttr *attr,
* Returns: /*! maximum number of jobs. */
* Always returns 0. int maxJobsTotal);
*****************************************************************************/
int TPAttrSetMaxJobsTotal(ThreadPoolAttr *attr, int maxJobsTotal);
/*!
/**************************************************************************** * \brief Returns various statistics about the thread pool.
* Function: ThreadPoolGetStats
* *
* Description: * Only valid if STATS has been defined.
* Returns various statistics about the *
* thread pool. * \return Always returns 0.
* Only valid if STATS has been defined. */
* Parameters:
* ThreadPool *tp - valid initialized threadpool
* ThreadPoolStats *stats - valid stats, out parameter
* Returns:
* Always returns 0.
*****************************************************************************/
#ifdef STATS #ifdef STATS
EXPORT_SPEC int ThreadPoolGetStats(ThreadPool *tp, ThreadPoolStats *stats); EXPORT_SPEC int ThreadPoolGetStats(
/*! Valid initialized threadpool. */
EXPORT_SPEC void ThreadPoolPrintStats(ThreadPoolStats *stats); ThreadPool *tp,
/*! Valid stats, out parameter. */
ThreadPoolStats *stats);
#else #else
static UPNP_INLINE int ThreadPoolGetStats(ThreadPool *tp, ThreadPoolStats *stats) {} static UPNP_INLINE int ThreadPoolGetStats(
/*! Valid initialized threadpool. */
static UPNP_INLINE void ThreadPoolPrintStats(ThreadPoolStats *stats) {} ThreadPool *tp,
/*! Valid stats, out parameter. */
ThreadPoolStats *stats) {}
#endif #endif
/*!
* \brief
*/
#ifdef STATS
EXPORT_SPEC void ThreadPoolPrintStats(
/*! . */
ThreadPoolStats *stats);
#else
static UPNP_INLINE void ThreadPoolPrintStats(
/*! . */
ThreadPoolStats *stats) {}
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* THREADPOOL_H */ #endif /* THREADPOOL_H */

View File

@ -29,35 +29,31 @@
* *
******************************************************************************/ ******************************************************************************/
#ifndef TIMERTHREAD_H #ifndef TIMERTHREAD_H
#define TIMERTHREAD_H #define TIMERTHREAD_H
/*! /*!
* \file * \file
*/ */
#include "FreeList.h" #include "FreeList.h"
#include "ithread.h" #include "ithread.h"
#include "LinkedList.h" #include "LinkedList.h"
#include "ThreadPool.h" #include "ThreadPool.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#define INVALID_EVENT_ID (-10 & 1<<29) #define INVALID_EVENT_ID (-10 & 1<<29)
/*! Timeout Types. */
/* Timeout Types */ typedef enum timeoutType {
/* absolute means in seconds from Jan 1, 1970 */ /*! seconds from Jan 1, 1970. */
/* relative means in seconds from current time */ ABS_SEC,
typedef enum timeoutType {ABS_SEC,REL_SEC} TimeoutType; /*! seconds from current time. */
REL_SEC
} TimeoutType;
/*! /*!
* A timer thread similar to the one in the Upnp SDK that allows * A timer thread similar to the one in the Upnp SDK that allows
@ -79,7 +75,6 @@ typedef struct TIMERTHREAD
ThreadPool *tp; ThreadPool *tp;
} TimerThread; } TimerThread;
/*! /*!
* Struct to contain information for a timer event. * Struct to contain information for a timer event.
* *
@ -95,7 +90,6 @@ typedef struct TIMEREVENT
int id; int id;
} TimerEvent; } TimerEvent;
/*! /*!
* \brief Initializes and starts timer thread. * \brief Initializes and starts timer thread.
* *
@ -109,7 +103,6 @@ int TimerThreadInit(
* lifetime of timer. Timer must be shutdown BEFORE thread pool. */ * lifetime of timer. Timer must be shutdown BEFORE thread pool. */
ThreadPool *tp); ThreadPool *tp);
/*! /*!
* \brief Schedules an event to run at a specified time. * \brief Schedules an event to run at a specified time.
* *
@ -132,7 +125,6 @@ int TimerThreadSchedule(
/*! [in] Id of timer event. (out, can be null). */ /*! [in] Id of timer event. (out, can be null). */
int *id); int *id);
/*! /*!
* \brief Removes an event from the timer Q. * \brief Removes an event from the timer Q.
* *
@ -148,7 +140,6 @@ int TimerThreadRemove(
/*! [in] Space for thread pool job. */ /*! [in] Space for thread pool job. */
ThreadPoolJob *out); ThreadPoolJob *out);
/*! /*!
* \brief Shutdown the timer thread. * \brief Shutdown the timer thread.
* *
@ -162,7 +153,6 @@ int TimerThreadShutdown(
/*! [in] Valid timer thread pointer. */ /*! [in] Valid timer thread pointer. */
TimerThread *timer); TimerThread *timer);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -1,177 +1,111 @@
/////////////////////////////////////////////////////////////////////////// /**************************************************************************
// *
// Copyright (c) 2000-2003 Intel Corporation * Copyright (c) 2000-2003 Intel Corporation
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// * Redistributions of source code must retain the above copyright notice, * - Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice, * - Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// * Neither name of Intel Corporation nor the names of its contributors * - Neither name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// *
/////////////////////////////////////////////////////////////////////////// **************************************************************************/
#include "FreeList.h" #include "FreeList.h"
#include <assert.h> #include <assert.h>
#include <stdlib.h> #include <stdlib.h>
/**************************************************************************** int FreeListInit(FreeList *free_list, size_t elementSize, int maxFreeListLength)
* Function: FreeListInit
*
* Description:
* Initializes Free List. Must be called first.
* And only once for FreeList.
* Parameters:
* free_list - must be valid, non null, pointer to a linked list.
* size_t - size of elements to store in free list
* maxFreeListSize - max size that the free list can grow to
* before returning memory to O.S.
* Returns:
* 0 on success. Nonzero on failure.
* Always returns 0.
*****************************************************************************/
int
FreeListInit( FreeList * free_list,
size_t elementSize,
int maxFreeListLength )
{ {
assert( free_list != NULL ); assert(free_list != NULL);
if( free_list == NULL ) if (free_list == NULL)
return EINVAL; return EINVAL;
free_list->element_size = elementSize;
free_list->maxFreeListLength = maxFreeListLength;
free_list->head = NULL;
free_list->freeListLength = 0;
free_list->element_size = elementSize; return 0;
free_list->maxFreeListLength = maxFreeListLength;
free_list->head = NULL;
free_list->freeListLength = 0;
return 0;
} }
/**************************************************************************** void *FreeListAlloc(FreeList *free_list)
* Function: FreeListAlloc
*
* Description:
* Allocates chunk of set size.
* If a free item is available in the list, returnes the stored item.
* Otherwise calls the O.S. to allocate memory.
* Parameters:
* free_list - must be valid, non null, pointer to a linked list.
* Returns:
* Non NULL on success. NULL on failure.
*****************************************************************************/
void *
FreeListAlloc( FreeList * free_list )
{ {
FreeListNode *ret = NULL; FreeListNode *ret = NULL;
assert( free_list != NULL ); assert(free_list != NULL);
if( free_list == NULL ) if (free_list == NULL)
return NULL; return NULL;
if( free_list->head ) { if (free_list->head) {
ret = free_list->head; ret = free_list->head;
free_list->head = free_list->head->next; free_list->head = free_list->head->next;
free_list->freeListLength--; free_list->freeListLength--;
} else { } else {
ret = malloc( free_list->element_size ); ret = malloc(free_list->element_size);
} }
return ret; return ret;
} }
/**************************************************************************** int FreeListFree(FreeList *free_list, void *element)
* Function: FreeListFree
*
* Description:
* Returns an item to the Free List.
* If the free list is smaller than the max size than
* adds the item to the free list.
* Otherwise returns the item to the O.S.
* Parameters:
* free_list - must be valid, non null, pointer to a free list.
* element - must be a pointer allocated by FreeListAlloc
* Returns:
* 0 on success. Nonzero on failure.
* Always returns 0.
*****************************************************************************/
int
FreeListFree( FreeList * free_list,
void *element )
{ {
FreeListNode *temp = NULL;
FreeListNode *temp = NULL; assert(free_list != NULL);
assert( free_list != NULL ); if (free_list == NULL)
return EINVAL;
if (element != NULL &&
free_list->freeListLength + 1 < free_list->maxFreeListLength) {
free_list->freeListLength++;
temp = (FreeListNode *)element;
temp->next = free_list->head;
free_list->head = temp;
} else {
free(element);
}
if( free_list == NULL ) return 0;
return EINVAL;
if( ( element != NULL ) &&
( ( free_list->freeListLength + 1 ) <
free_list->maxFreeListLength ) ) {
free_list->freeListLength++;
temp = ( FreeListNode * ) element;
temp->next = free_list->head;
free_list->head = temp;
} else {
free( element );
}
return 0;
} }
/**************************************************************************** int FreeListDestroy(FreeList *free_list)
* Function: FreeListDestroy
*
* Description:
* Releases the resources stored with the free list.
* Parameters:
* free_list - must be valid, non null, pointer to a linked list.
* Returns:
* 0 on success. Nonzero on failure.
* Always returns 0.
*****************************************************************************/
int
FreeListDestroy( FreeList * free_list )
{ {
FreeListNode *temp = NULL; FreeListNode *temp = NULL;
int i = 0; int i = 0;
assert( free_list != NULL ); assert(free_list != NULL);
if( free_list == NULL ) if (!free_list)
return EINVAL; return EINVAL;
while (free_list->head) {
i++;
temp = free_list->head->next;
free(free_list->head);
free_list->head = temp;
}
free_list->freeListLength = 0;
while( free_list->head ) { return 0;
i++;
temp = free_list->head->next;
free( free_list->head );
free_list->head = temp;
}
free_list->freeListLength = 0;
return 0;
} }

View File

@ -29,519 +29,281 @@
* *
**************************************************************************/ **************************************************************************/
#include "LinkedList.h" #include "LinkedList.h"
#ifdef WIN32 #ifdef WIN32
/* Do not #include <sys/param.h> */ /* Do not #include <sys/param.h> */
#else #else
#include <sys/param.h> #include <sys/param.h>
#endif #endif
#if (defined(BSD) && BSD >= 199306) || defined(__OSX__) || defined(__APPLE__) #if (defined(BSD) && BSD >= 199306) || defined(__OSX__) || defined(__APPLE__)
#include <stdlib.h> #include <stdlib.h>
#else #else
#include <malloc.h> #include <malloc.h>
#endif #endif
#include <assert.h> #include <assert.h>
static int freeListNode(ListNode *node, LinkedList *list)
static int
freeListNode( ListNode * node,
LinkedList * list )
{ {
assert( list != NULL ); assert(list != NULL);
return FreeListFree( &list->freeNodeList, node ); return FreeListFree(&list->freeNodeList, node);
} }
/**************************************************************************** /*!
* Function: CreateListNode * \brief Dynamically creates a list node.
*
* Description:
* Creates a list node. Dynamically.
* *
* Parameters: * Parameters:
* void * item - the item to store * void * item - the item to store
* Returns: * Returns:
* The new node, NULL on failure. * The new node, NULL on failure.
*****************************************************************************/ */
static ListNode * static ListNode *CreateListNode(
CreateListNode( void *item, /*! the item to store. */
LinkedList * list ) void *item,
/*! The list to add it to. */
LinkedList *list)
{ {
ListNode *temp = NULL;
ListNode *temp = NULL; assert(list != NULL);
assert( list != NULL ); temp = (ListNode *)FreeListAlloc(&list->freeNodeList);
if (temp) {
temp->prev = NULL;
temp->next = NULL;
temp->item = item;
}
temp = ( ListNode * ) FreeListAlloc( &list->freeNodeList ); return temp;
if( temp ) {
temp->prev = NULL;
temp->next = NULL;
temp->item = item;
}
return temp;
} }
/**************************************************************************** int ListInit(LinkedList *list, cmp_routine cmp_func, free_function free_func)
* Function: ListInit
*
* Description:
* Initializes LinkedList. Must be called first.
* And only once for List.
* Parameters:
* list - must be valid, non null, pointer to a linked list.
* cmp_func - function used to compare items. (May be NULL)
* free_func - function used to free items. (May be NULL)
* Returns:
* 0 on success, EOUTOFMEM on failure.
*****************************************************************************/
int
ListInit( LinkedList * list,
cmp_routine cmp_func,
free_function free_func )
{ {
int retCode = 0;
int retCode = 0; assert(list != NULL);
assert( list != NULL ); if (!list)
return EINVAL;
list->size = 0;
list->cmp_func = cmp_func;
list->free_func = free_func;
retCode = FreeListInit(&list->freeNodeList, sizeof(ListNode), FREELISTSIZE);
if( list == NULL ) assert(retCode == 0);
return EINVAL;
list->size = 0; list->head.item = NULL;
list->cmp_func = cmp_func; list->head.next = &list->tail;
list->free_func = free_func; list->head.prev = NULL;
list->tail.item = NULL;
list->tail.prev = &list->head;
list->tail.next = NULL;
retCode = return 0;
FreeListInit( &list->freeNodeList, sizeof( ListNode ),
FREELISTSIZE );
assert( retCode == 0 );
list->head.item = NULL;
list->head.next = &list->tail;
list->head.prev = NULL;
list->tail.item = NULL;
list->tail.prev = &list->head;
list->tail.next = NULL;
return 0;
} }
/**************************************************************************** ListNode *ListAddHead(LinkedList *list, void *item)
* Function: ListAddHead
*
* Description:
* Adds a node to the head of the list.
* Node gets immediately after list.head.
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
* void * item - item to be added
* Returns:
* The pointer to the ListNode on success, NULL on failure.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode *
ListAddHead( LinkedList * list,
void *item )
{ {
assert( list != NULL ); assert(list != NULL);
if( list == NULL ) if (list == NULL)
return NULL; return NULL;
return ListAddAfter( list, item, &list->head ); return ListAddAfter(list, item, &list->head);
} }
/**************************************************************************** ListNode *ListAddTail(LinkedList *list, void *item)
* Function: ListAddTail
*
* Description:
* Adds a node to the tail of the list.
* Node gets added immediately before list.tail.
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
* void * item - item to be added
* Returns:
* The pointer to the ListNode on success, NULL on failure.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode *
ListAddTail( LinkedList * list,
void *item )
{ {
assert( list != NULL ); assert(list != NULL);
if( list == NULL ) if (!list)
return NULL; return NULL;
return ListAddBefore( list, item, &list->tail ); return ListAddBefore(list, item, &list->tail);
} }
/**************************************************************************** ListNode *ListAddAfter(LinkedList *list, void *item, ListNode *bnode)
* Function: ListAddAfter
*
* Description:
* Adds a node after the specified node.
* Node gets added immediately after bnode.
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
* void * item - item to be added
* ListNode * bnode - node to add after
* Returns:
* The pointer to the ListNode on success, NULL on failure.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode *
ListAddAfter( LinkedList * list,
void *item,
ListNode * bnode )
{ {
ListNode *newNode = NULL; ListNode *newNode = NULL;
assert( list != NULL ); assert(list != NULL);
if( ( list == NULL ) || ( bnode == NULL ) ) if (!list || !bnode)
return NULL; return NULL;
newNode = CreateListNode(item, list);
if (newNode) {
ListNode *temp = bnode->next;
newNode = CreateListNode( item, list ); bnode->next = newNode;
if( newNode ) { newNode->prev = bnode;
ListNode *temp = bnode->next; newNode->next = temp;
temp->prev = newNode;
list->size++;
bnode->next = newNode; return newNode;
newNode->prev = bnode; }
newNode->next = temp;
temp->prev = newNode; return NULL;
list->size++;
return newNode;
}
return NULL;
} }
/**************************************************************************** ListNode *ListAddBefore(LinkedList *list, void *item, ListNode *anode)
* Function: ListAddBefore
*
* Description:
* Adds a node before the specified node.
* Node gets added immediately before anode.
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
* ListNode * anode - node to add the in front of.
* void * item - item to be added
* Returns:
* The pointer to the ListNode on success, NULL on failure.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode *
ListAddBefore( LinkedList * list,
void *item,
ListNode * anode )
{ {
ListNode *newNode = NULL; ListNode *newNode = NULL;
assert( list != NULL ); assert(list != NULL);
if( ( list == NULL ) || ( anode == NULL ) ) if (!list || !anode)
return NULL; return NULL;
newNode = CreateListNode(item, list);
if (newNode) {
ListNode *temp = anode->prev;
newNode = CreateListNode( item, list ); anode->prev = newNode;
newNode->next = anode;
newNode->prev = temp;
temp->next = newNode;
list->size++;
if( newNode ) { return newNode;
ListNode *temp = anode->prev; }
anode->prev = newNode; return NULL;
newNode->next = anode;
newNode->prev = temp;
temp->next = newNode;
list->size++;
return newNode;
}
return NULL;
} }
/**************************************************************************** void *ListDelNode(LinkedList *list, ListNode *dnode, int freeItem)
* Function: ListDelNode
*
* Description:
* Removes a node from the list
* The memory for the node is freed but the
* the memory for the items are not.
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
* ListNode *dnode - done to delete.
* Returns:
* The pointer to the item stored in node on success, NULL on failure.
* Precondition:
* The list has been initialized.
*****************************************************************************/
void *
ListDelNode( LinkedList * list,
ListNode * dnode,
int freeItem )
{ {
void *temp; void *temp;
assert( list != NULL ); assert(list != NULL);
assert( dnode != &list->head ); assert(dnode != &list->head);
assert( dnode != &list->tail ); assert(dnode != &list->tail);
if( ( list == NULL ) || if (!list || dnode == &list->head || dnode == &list->tail || !dnode)
( dnode == &list->head ) || return NULL;
( dnode == &list->tail ) || ( dnode == NULL ) ) { temp = dnode->item;
return NULL; dnode->prev->next = dnode->next;
} dnode->next->prev = dnode->prev;
freeListNode(dnode, list);
list->size--;
if (freeItem && list->free_func) {
list->free_func(temp);
temp = NULL;
}
temp = dnode->item; return temp;
dnode->prev->next = dnode->next;
dnode->next->prev = dnode->prev;
freeListNode( dnode, list );
list->size--;
if( freeItem && list->free_func ) {
list->free_func( temp );
temp = NULL;
}
return temp;
} }
/**************************************************************************** int ListDestroy(LinkedList *list, int freeItem)
* Function: ListDestroy
*
* Description:
* Removes all memory associated with list nodes.
* Does not free LinkedList *list.
* Items stored in the list are not freed, only nodes are.
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
* Returns:
* 0 on success. Nonzero on failure.
* Always returns 0.
* Precondition:
* The list has been initialized.
*****************************************************************************/
int
ListDestroy( LinkedList * list,
int freeItem )
{ {
ListNode *dnode = NULL; ListNode *dnode = NULL;
ListNode *temp = NULL; ListNode *temp = NULL;
if( list == NULL ) if(!list)
return EINVAL; return EINVAL;
for( dnode = list->head.next; dnode != &list->tail; ) { for (dnode = list->head.next; dnode != &list->tail; ) {
temp = dnode->next; temp = dnode->next;
ListDelNode( list, dnode, freeItem ); ListDelNode(list, dnode, freeItem);
dnode = temp; dnode = temp;
} }
list->size = 0;
FreeListDestroy(&list->freeNodeList);
list->size = 0; return 0;
FreeListDestroy( &list->freeNodeList );
return 0;
} }
/**************************************************************************** ListNode *ListHead(LinkedList *list)
* Function: ListHead
*
* Description:
* Returns the head of the list.
*
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
*
* Returns:
* The head of the list. NULL if list is empty.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode *
ListHead( LinkedList * list )
{ {
assert( list != NULL ); assert(list != NULL);
if( list == NULL ) if (!list)
return NULL; return NULL;
if( list->size == 0 ) if (!list->size)
return NULL; return NULL;
else else
return list->head.next; return list->head.next;
} }
/**************************************************************************** ListNode *ListTail(LinkedList *list)
* Function: ListTail
*
* Description:
* Returns the tail of the list.
*
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
*
* Returns:
* The tail of the list. NULL if list is empty.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode *
ListTail( LinkedList * list )
{ {
assert( list != NULL ); assert(list != NULL);
if( list == NULL ) if (!list)
return NULL; return NULL;
if( list->size == 0 ) if (!list->size)
return NULL; return NULL;
else else
return list->tail.prev; return list->tail.prev;
} }
/**************************************************************************** ListNode *ListNext(LinkedList *list, ListNode *node)
* Function: ListNext
*
* Description:
* Returns the next item in the list.
*
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
*
* Returns:
* The next item in the list. NULL if there are no more items in list.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode *
ListNext( LinkedList * list,
ListNode * node )
{ {
assert( list != NULL ); assert(list != NULL);
assert( node != NULL ); assert(node != NULL);
if( ( list == NULL ) || ( node == NULL ) ) if (!list || !node)
return NULL; return NULL;
if (node->next == &list->tail)
if( node->next == &list->tail ) return NULL;
return NULL; else
else return node->next;
return node->next;
} }
/**************************************************************************** ListNode *ListPrev(LinkedList *list, ListNode *node)
* Function: ListPrev
*
* Description:
* Returns the previous item in the list.
*
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
*
* Returns:
* The previous item in the list. NULL if there are no more items in list.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode *
ListPrev( LinkedList * list,
ListNode * node )
{ {
assert( list != NULL ); assert(list != NULL);
assert( node != NULL ); assert(node != NULL);
if( ( list == NULL ) || ( node == NULL ) ) if (!list || !node)
return NULL; return NULL;
if( node->prev == &list->head ) if (node->prev == &list->head)
return NULL; return NULL;
else else
return node->prev; return node->prev;
} }
/**************************************************************************** ListNode *ListFind(LinkedList *list, ListNode *start, void *item)
* Function: ListFind
*
* Description:
* Finds the specified item in the list.
* Uses the compare function specified in ListInit. If compare function
* is NULL then compares items as pointers.
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
* ListNode *start - the node to start from, NULL if to start from
* beginning.
* void * item - the item to search for.
* Returns:
* The node containing the item. NULL if no node contains the item.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode *
ListFind( LinkedList * list,
ListNode * start,
void *item )
{ {
ListNode *finger = NULL;
ListNode *finger = NULL; if (!list)
return NULL;
if (!start)
start = &list->head;
if( list == NULL ) assert(start);
return NULL;
if( start == NULL ) finger = start->next;
start = &list->head;
assert( start ); assert(finger);
finger = start->next; while (finger != &list->tail) {
if (list->cmp_func) {
assert( finger ); if (list->cmp_func(item, finger->item))
return finger;
while( finger != &list->tail ) { } else {
if( list->cmp_func ) { if (item == finger->item)
if( list->cmp_func( item, finger->item ) ) return finger;
return finger; }
} else { finger = finger->next;
if( item == finger->item ) }
return finger;
}
finger = finger->next;
}
return NULL;
return NULL;
} }
/**************************************************************************** long ListSize(LinkedList *list)
* Function: ListSize
*
* Description:
* Returns the size of the list.
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
* Returns:
* The number of items in the list.
* Precondition:
* The list has been initialized.
*****************************************************************************/
int
ListSize( LinkedList * list )
{ {
assert( list != NULL ); assert(list != NULL);
if( list == NULL ) if (!list)
return EINVAL; return EINVAL;
return list->size; return list->size;
} }

File diff suppressed because it is too large Load Diff

View File

@ -29,18 +29,14 @@
* *
******************************************************************************/ ******************************************************************************/
/*! /*!
* \file * \file
*/ */
#include "TimerThread.h" #include "TimerThread.h"
#include <assert.h> #include <assert.h>
/*! /*!
* \brief Deallocates a dynamically allocated TimerEvent. * \brief Deallocates a dynamically allocated TimerEvent.
*/ */
@ -55,7 +51,6 @@ static void FreeTimerEvent(
FreeListFree(&timer->freeEvents, event); FreeListFree(&timer->freeEvents, event);
} }
/*! /*!
* \brief Implements timer thread. * \brief Implements timer thread.
* *
@ -67,46 +62,34 @@ static void *TimerThreadWorker(
{ {
TimerThread *timer = ( TimerThread * ) arg; TimerThread *timer = ( TimerThread * ) arg;
ListNode *head = NULL; ListNode *head = NULL;
TimerEvent *nextEvent = NULL; TimerEvent *nextEvent = NULL;
time_t currentTime = 0; time_t currentTime = 0;
time_t nextEventTime = 0; time_t nextEventTime = 0;
struct timespec timeToWait; struct timespec timeToWait;
int tempId; int tempId;
assert( timer != NULL ); assert( timer != NULL );
ithread_mutex_lock( &timer->mutex ); ithread_mutex_lock( &timer->mutex );
while (1) {
while( 1 ) /* mutex should always be locked at top of loop */
{ /* Check for shutdown. */
//mutex should always be locked at top of loop if (timer->shutdown) {
//Check for shutdown
if( timer->shutdown )
{
timer->shutdown = 0; timer->shutdown = 0;
ithread_cond_signal( &timer->condition ); ithread_cond_signal( &timer->condition );
ithread_mutex_unlock( &timer->mutex ); ithread_mutex_unlock( &timer->mutex );
return NULL; return NULL;
} }
nextEvent = NULL; nextEvent = NULL;
/* Get the next event if possible. */
//Get the next event if possible if (timer->eventQ.size > 0) {
if( timer->eventQ.size > 0 )
{
head = ListHead( &timer->eventQ ); head = ListHead( &timer->eventQ );
nextEvent = ( TimerEvent * ) head->item; nextEvent = ( TimerEvent * ) head->item;
nextEventTime = nextEvent->eventTime; nextEventTime = nextEvent->eventTime;
} }
currentTime = time(NULL);
currentTime = time( NULL ); /* If time has elapsed, schedule job. */
if (nextEvent && currentTime >= nextEventTime) {
//If time has elapsed, schedule job
if( ( nextEvent != NULL ) && ( currentTime >= nextEventTime ) )
{
if( nextEvent->persistent ) { if( nextEvent->persistent ) {
ThreadPoolAddPersistent( timer->tp, &nextEvent->job, ThreadPoolAddPersistent( timer->tp, &nextEvent->job,
&tempId ); &tempId );
@ -117,8 +100,7 @@ static void *TimerThreadWorker(
FreeTimerEvent( timer, nextEvent ); FreeTimerEvent( timer, nextEvent );
continue; continue;
} }
if (nextEvent) {
if( nextEvent != NULL ) {
timeToWait.tv_nsec = 0; timeToWait.tv_nsec = 0;
timeToWait.tv_sec = nextEvent->eventTime; timeToWait.tv_sec = nextEvent->eventTime;
ithread_cond_timedwait( &timer->condition, &timer->mutex, ithread_cond_timedwait( &timer->condition, &timer->mutex,
@ -146,16 +128,15 @@ static int CalculateEventTime(
assert( timeout != NULL ); assert( timeout != NULL );
if( type == ABS_SEC ) if (type == ABS_SEC)
return 0; return 0;
else if( type == REL_SEC ) { else /*if (type == REL_SEC) */{
time( &now ); time(&now);
( *timeout ) += now; ( *timeout ) += now;
return 0; return 0;
} }
return -1; return -1;
} }
/*! /*!
@ -246,10 +227,8 @@ int TimerThreadInit(TimerThread *timer, ThreadPool *tp)
} }
return rc; return rc;
} }
int TimerThreadSchedule( int TimerThreadSchedule(
TimerThread *timer, TimerThread *timer,
time_t timeout, time_t timeout,
@ -258,7 +237,6 @@ int TimerThreadSchedule(
Duration duration, Duration duration,
int *id) int *id)
{ {
int rc = EOUTOFMEM; int rc = EOUTOFMEM;
int found = 0; int found = 0;
int tempId = 0; int tempId = 0;
@ -291,35 +269,25 @@ int TimerThreadSchedule(
} }
tempNode = ListHead( &timer->eventQ ); tempNode = ListHead( &timer->eventQ );
//add job to Q /* add job to Q. Q is ordered by eventTime with the head of the Q being
//Q is ordered by eventTime * the next event. */
//with the head of the Q being the next event
while( tempNode != NULL ) { while( tempNode != NULL ) {
temp = ( TimerEvent * ) tempNode->item; temp = ( TimerEvent * ) tempNode->item;
if( temp->eventTime >= timeout ) if( temp->eventTime >= timeout ) {
{ if (ListAddBefore( &timer->eventQ, newEvent, tempNode))
if( ListAddBefore( &timer->eventQ, newEvent, tempNode ) !=
NULL )
rc = 0; rc = 0;
found = 1; found = 1;
break; break;
} }
tempNode = ListNext( &timer->eventQ, tempNode ); tempNode = ListNext( &timer->eventQ, tempNode );
} }
/* add to the end of Q. */
//add to the end of Q if (!found) {
if( !found ) {
if( ListAddTail( &timer->eventQ, newEvent ) != NULL ) if( ListAddTail( &timer->eventQ, newEvent ) != NULL )
rc = 0; rc = 0;
} }
//signal change in Q /* signal change in Q. */
if( rc == 0 ) { if( rc == 0 ) {
ithread_cond_signal( &timer->condition ); ithread_cond_signal( &timer->condition );
} else { } else {
FreeTimerEvent( timer, newEvent ); FreeTimerEvent( timer, newEvent );
@ -330,7 +298,6 @@ int TimerThreadSchedule(
return rc; return rc;
} }
int TimerThreadRemove( int TimerThreadRemove(
TimerThread *timer, TimerThread *timer,
int id, int id,
@ -369,7 +336,6 @@ int TimerThreadRemove(
return rc; return rc;
} }
int TimerThreadShutdown(TimerThread *timer) int TimerThreadShutdown(TimerThread *timer)
{ {
ListNode *tempNode2 = NULL; ListNode *tempNode2 = NULL;
@ -386,9 +352,7 @@ int TimerThreadShutdown(TimerThread *timer)
timer->shutdown = 1; timer->shutdown = 1;
tempNode = ListHead( &timer->eventQ ); tempNode = ListHead( &timer->eventQ );
//Delete nodes in Q /* Delete nodes in Q. Call registered free function on argument. */
//call registered free function
//on argument
while( tempNode != NULL ) { while( tempNode != NULL ) {
TimerEvent *temp = ( TimerEvent * ) tempNode->item; TimerEvent *temp = ( TimerEvent * ) tempNode->item;
@ -406,19 +370,17 @@ int TimerThreadShutdown(TimerThread *timer)
ithread_cond_broadcast( &timer->condition ); ithread_cond_broadcast( &timer->condition );
while( timer->shutdown ) //wait for timer thread to shutdown while (timer->shutdown) {
{ /* wait for timer thread to shutdown. */
ithread_cond_wait( &timer->condition, &timer->mutex ); ithread_cond_wait( &timer->condition, &timer->mutex );
} }
ithread_mutex_unlock(&timer->mutex);
ithread_mutex_unlock( &timer->mutex ); /* destroy condition. */
while(ithread_cond_destroy(&timer->condition) != 0) {
//destroy condition
while( ithread_cond_destroy( &timer->condition ) != 0 ) {
} }
/* destroy mutex. */
//destroy mutex while (ithread_mutex_destroy(&timer->mutex) != 0) {
while( ithread_mutex_destroy( &timer->mutex ) != 0 ) {
} }
return 0; return 0;