/********************************************************************** File: sync_int.h BETA atomic lock and manipulation of integral values via POSIX threads. Copyright (C) 1998-2006 Michael M. Lampkin Contact at michael.lampkinieee.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License version 2 along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 **********************************************************************/ /********************************************************************** This is a basic C library that began ( and still exists ) as C++ template classes designed to allow a variety of atomic operations on numeric type variables. The re-write of these functions in C was done primarily out of boredom and not for any specific real life project. The major categories and the functions provided are: Initialization and Destruction: sync_init sync_init_default sync_destroy Basic Get/Set Operations: sync_get sync_set Basic Operations: sync_inc sync_dec sync_complement sync_negate Arithmetic Operations: sync_add sync_sub sync_mul sync_div sync_mod Bitwise Operations: sync_and sync_or sync_xor sync_lshift sync_rshift Basic Comparison Operations: sync_cmp Basic Operations followed by Comparison: sync_inc_cmp sync_dec_cmp sync_complement_cmp sync_negate_cmp Arithmetic Operations followed by Comparison: sync_add_cmp sync_sub_cmp sync_mul_cmp sync_div_cmp sync_mod_cmp Bitwise Operations followed by Comparison: sync_and_cmp sync_or_cmp sync_xor_cmp sync_lshift_cmp sync_rshift_cmp Basic Operations followed by User Function sync_inc_exec sync_dec_exec sync_complement_exec sync_negate_exec Arithmethic Operations followed by User Function sync_add_exec sync_sub_exec sync_mul_exec sync_div_exec sync_mod_exec Bitwise Operations followed by User Function sync_and_exec sync_or_exec sync_xor_exec sync_lshift_exec sync_rshift_exec Comparison Operation followed by Conditional User Function sync_cmp_exec Basic Operations followed by Conditional User Function sync_inc_cmp_exec sync_dec_cmp_exec sync_complement_cmp_exec sync_negate_cmp_exec Arithmetic Operations followed by Conditional User Function sync_add_cmp_exec sync_sub_cmp_exec sync_mul_cmp_exec sync_div_cmp_exec sync_mod_cmp_exec Bitwise Operations followed by Conditional User Function sync_and_cmp_exec sync_or_cmp_exec sync_xor_cmp_exec sync_lshift_cmp_exec sync_rshift_cmp_exec Basic Operations followed by Asynchronous User Function sync_inc_async_exec sync_dec_async_exec sync_complement_async_exec sync_negate_async_exec Arithmetic Operations followed by Asynchronous User Function sync_add_async_exec sync_sub_async_exec sync_mul_async_exec sync_div_async_exec sync_mod_async_exec Bitwise Operations followed by Asynchronous User Function sync_and_async_exec sync_or_async_exec sync_xor_async_exec sync_lshift_async_exec sync_rshift_async_exec Comparison followed by Conditional Asynchronous User Function sync_cmp_async_exec Basic Operations followed by Conditional Asynchronous User Function sync_inc_cmp_async_exec sync_dec_cmp_async_exec sync_complement_cmp_async_exec sync_negate_cmp_async_exec Arithmetic Operations followed by Conditional Asynchronous User Function sync_add_cmp_async_exec sync_sub_cmp_async_exec sync_mul_cmp_async_exec sync_div_cmp_async_exec sync_mod_cmp_async_exec Bitwise Operations followed by Conditional Asynchronous User Function sync_and_cmp_async_exec sync_or_cmp_async_exec sync_xor_cmp_async_exec sync_lshift_cmp_async_exec sync_rshift_cmp_async_exec Further descriptions of the various functions are contained below. I need to make a few comments about the code... As I previously mentioned, this comes from some C++ template classes that I created many years ago. I just created it and have not used this code in any projects to date though I did do a little bit of preliminary testing. This means there may be bugs, many bugs, in this implementation and you are using it at your own risk. On that note, if you do find any errors or strange things that should be corrected, please feel free to let me know. I'll fix them as time permits. Many of the functions COULD be further folded so that they are better utilizing each other. I didn't do this in most cases simply so that no hit would be taken due to the overhead from chaining multiple function calls. This is a very minor optimization which definitely results in compiled code which is quite larger than necessary. On the other hand if someone wants a bit more speed then as often as not, this is the way that it is done and after all, this code deals with synchronizing sections of code where speed is normally a major concern. The return errors are all passed back via errno. I did have the option of requiring each function to have an extra parameter to carry any errors. This was not done because I felt that if someone used the code and their code base was fully tested they why should I force them to carry the overhead of passing in that extra parameter? This way they can just ignore errno if they know there are no problems and not be penalized. Either way I know it may look a bit odd ;-) **********************************************************************/ /** If this code is not first in compilation order then you should duplicate at least the first define in your primary header file. **/ #define _POSIX_C_SOURCE 200112L #define _XOPEN_SOURCE 600 #include #include #include #include #include #include /** Change the following if you want to use a different mutex type for synchronization. **/ #define MUTEX_TYPE__ PTHREAD_MUTEX_ERRORCHECK /** The standard synchronized wrapper using a POSIX mutex and int as defined on the system. This structure should only be manipulated using the supplied functions. Direct modification may result in indeterminate behavior of the code. **/ typedef struct { pthread_mutex_t mutex; int value; } sync_int; /** Function: sync_init Description: Initialize the internal components of the specified atom. The internal value of the atom will be set to the one specified during the function call. Parameters: atom - a pointer to an uninitialized sync_int structure. value - the desired value of the atom. Return: SUCCESS: This function will return a zero on success. FAILURE: This function will return a non-zero with the errno set to an appropriate value on failure. Failure is typically caused by a lack of available system resources. Additionally this function can fail in an undefined manner, though an errno of EBUSY is expected, if this function is called on an atom which has previously been initialized but not destroyed. Possible errno values are: ENOMEM : There is insufficient memory exists to initialize the internal mutex. EAGAIN : There are insufficient resources other than memory to initialize the internal mutex. EBUSY : The specified atom is already initialized. **/ extern int sync_init( sync_int * atom, int value ); /** Function: sync_init_default Description: Initialize the internal components of the specified atom. The held value of the atom will be set to zero. Parameters: atom - a pointer to an uninitialized sync_int structure. Return: SUCCESS: This function will return a zero on success. FAILURE: This function will return a non-zero with the errno set to an appropriate value on failure. Failure is typically caused by a lack of available system resources. Additionally this function can fail in an undefined manner, though an errno of EBUSY is expected, if this function is called on an atom which has previously been initialized but not destroyed. Possible errno values are: ENOMEM : There is insufficient memory exists to initialize the internal mutex. EAGAIN : There are insufficient resources other than memory to initialize the internal mutex. EBUSY : The specified atom is already initialized. **/ extern int sync_init_default( sync_int * atom ); /** Function: sync_destroy Description: Free the internal resources allocated to the sync_int object during initialization. Once destroyed, the sync_int must be re-initialized before re-use. Parameters: atom - a pointer to a previously initialized but not yet destroyed sync_int structure. Return: SUCCESS: This function will return a zero on success. FAILURE: This function will return a non-zero with the errno set to an appropriate value on failure. Possible errno values are: EINVAL : The atom was not previously initialized and the attempt to free the internal mutex of the atom failed. EBUSY : The atom is currently in use and the internal lock being held by another thread. **/ extern int sync_destroy( sync_int * atom ); /** Function: sync_get Description: Retrieve the value of the specified atom in a synchronized manner. Parameters: atom - a pointer to an intialized sync_int structure. Return: SUCCESS: This function will return the atom's protected value on success. FAILURE: The return value of this function will be undefined with the errno set to an appropriate value on failure. Failure is typically caused by a lack of available system resources. Additionally this function can fail in an undefined manner, though an errno of EBUSY is expected, if this function is called on an sync_int which has previously been initialized but not destroyed. Possible errno values are: EINVAL : The specified atom has not been initialized and it's synchronization mutex is invalid. **/ extern int sync_get( sync_int * atom ); /** Function: sync_set Description: Set the value of the specified atom in a synchronized manner. Parameters: atom - a pointer to an intialized sync_int structure. Return: SUCCESS: This function will return the atom's previously contained protected value on success. FAILURE: The return value of this function will be undefined with the errno set to an appropriate value on failure. Failure is typically caused by a lack of available system resources. Additionally this function can fail in an undefined manner, though an errno of EBUSY is expected, if this function is called on an sync_int which has previously been initialized but not destroyed. Possible errno values are: EINVAL : The specified atom has not been initialized and it's synchronization mutex is invalid. **/ extern int sync_set( sync_int * atom, int value ); /** Function: sync_inc sync_dec sync_complement sync_negate Description: These functions will atomically modify the internally held value of the atom by performing the operation described by the last token of the function name. Parameters: atom - a pointer to a previously intialized sync_int structure. Return: SUCCESS: Thes functions will return the atom's internal value AFTER the indicated modification has been performed. FAILURE: The return value of this function will be undefined with the errno set to an appropriate value on failure. Possible errno values are: EINVAL : The specified atom has not been initialized and it's synchronization mutex is invalid. **/ extern int sync_inc( sync_int * atom); extern int sync_dec( sync_int * atom ); extern int sync_complement( sync_int * atom ); extern int sync_negate( sync_int * atom); /** Function: Arithmetic Operations sync_add sync_sub sync_mul sync_div sync_mod Bitwise Operations sync_and sync_or sync_xor sync_lshift sync_rshift Description: These functions will atomically modify the internally held value of the atom by performing the operation indicated by the last token of the function name. The atom's value will be used as the left hand side and the value of modifier_rhs as the right hand side of the operation. Parameters: atom - a pointer to a previously intialized sync_int structure. modifier_rhs - the value to use as the rhs of the described operation. Return: SUCCESS: These functions will return the atom's internal value AFTER the arithmetic operation has been performed. FAILURE: The return value of this function will be undefined with the errno set to an appropriate value on failure. Possible errno values are: EINVAL : The specified atom has not been initialized and it's synchronization mutex is invalid. **/ extern int sync_add( sync_int * atom, int modifier_rhs ); extern int sync_sub( sync_int * atom, int modifier_rhs ); extern int sync_mul( sync_int * atom, int modifier_rhs ); extern int sync_div( sync_int * atom, int modifier_rhs ); extern int sync_mod( sync_int * atom, int modifier_rhs ); extern int sync_and( sync_int * atom, int modifier_rhs ); extern int sync_or( sync_int * atom, int modifier_rhs ); extern int sync_xor( sync_int * atom, int modifier_rhs ); extern int sync_lshift( sync_int * atom, int modifier_rhs ); extern int sync_rshift( sync_int * atom, int modifier_rhs ); /** Function: sync_cmp Description: This function will compare the atom's internal value to the specified compare_rhs value and return a result indicating the outcome of that comparison. If the compare_func parameter is NULL then the comparison will use the simple formula: result = atom->value - compare_rhs If the compare_func parameter is non-NULL is called and is performed by the specified function using the atom value as the left hand parameter and compare_rhs as the right hand parameter. The value of the atom is left unmodified by this operation. Parameters: atom - a pointer to a previously intialized sync_int structure. compare_func - a pointer to a user supplied comparison function. If NULL then the default operation will be utlized. compare_rhs - the value to use as the right hand side of the comparison operation, whether it be the default implementation or user supplied function. Return: SUCCESS: The functions will return the result of the comparison operation between the atom's value and the comparison_rhs value. If there is no user specified compare_func then the return value from the function will be: atom value < comparison_rhs : negative integer atom value == comparison_rhs : zero atom value > comparison_rhs : positive integer If there IS a user specified compare_func then the return value is dependent on the implementation of the user function. FAILURE: The return value of this function will be undefined with the errno set to an appropriate value on failure. Possible errno values are: EINVAL : The specified atom has not been initialized and it's synchronization mutex is invalid. **/ extern int sync_cmp( sync_int * atom, int ( * compare_func ) ( int, int ), int compare_rhs ); /** Function: sync_inc_cmp sync_dec_cmp sync_complement_cmp sync_negate_cmp Description: These functions will first atomically modify the value of the atom using the method described by the first token found after sync_ in the function name. After modification, the new value of the atom will be compared to the compare_rhs value and return a result indicating the outcome of that comparison. If the compare_func parameter is NULL then the comparison will use the simple formula: result = atom->value - compare_rhs If the compare_func parameter is non-NULL then the comparison is performed by the user function with the atom value as the left hand parameter and compare_rhs as the right hand parameter. The value of the atom is guaranteed to be left unmodified by the default comparison operation. Parameters: atom - a pointer to a previously intialized sync_int structure. compare_func - a pointer to a user supplied comparison function. If NULL then the default operation will be utlized. compare_rhs - the value to use as the right hand side of the comparison operation, whether it be the default implementation or user supplied function. Return: SUCCESS: This function will return the result of the comparison operation between the atom's value and the comparison_rhs value. If there is no user specified compare_func then the return value from the function will be: atom value < comparison_rhs : negative integer atom value == comparison_rhs : zero atom value > comparison_rhs : positive integer If there IS a user specified compare_func then the return value is dependent on the internal implementation of that function. FAILURE: The return value of this function will be undefined with the errno set to an appropriate value on failure. Possible errno values are: EINVAL : The specified atom has not been initialized and it's synchronization mutex is invalid. **/ extern int sync_inc_cmp( sync_int * atom, int ( * compare_func ) ( int, int ), int compare_rhs ); extern int sync_dec_cmp( sync_int * atom, int ( * compare_func ) ( int, int ), int compare_rhs ); extern int sync_complement_cmp( sync_int * atom, int ( * compare_func ) ( int, int ), int compare_rhs ); extern int sync_negate_cmp( sync_int * atom, int ( * compare_func ) ( int, int ), int compare_rhs ); /** Function: Arithmetic Operation followed by Comparison sync_add_cmp sync_sub_cmp sync_mul_cmp sync_div_cmp sync_mod_cmp Bitwise Operation followed by Comparison sync_and_cmp sync_or_cmp sync_xor_cmp sync_lshift_cmp sync_rshift_cmp Description: These functions will first atomically modify the value of the atom using the arithmetic operation described by the first token found after sync in the function name. The arithmetic operation will use the value of the atom as the lhs and the value of modifier_rhs as the rhs. After the arithmetic operation is complete, the new value of the atom will be compared to the compare_rhs value and return a value indicating the result of that comparison. If the compare_func parameter is NULL then the comparison will use the simple formula: result = atom->value - compare_rhs If the compare_func parameter is non-NULL then the comparison is performed by the user function with the atom value as the left hand parameter and compare_rhs as the right hand parameter. The value of the atom is guaranteed to be left unmodified by the default comparison operation. Parameters: atom - a pointer to a previously intialized sync_int structure. modifier_rhs - the value to use as the right hand side of the modification op. compare_func - a pointer to a user supplied comparison function. If NULL then the default operation will be utlized. compare_rhs - the value to use as the right hand side of the comparison operation, whether it be the default implementation or user supplied function. Return: SUCCESS: This function will return the value of the comparison operation between the atom's value and the comparison_rhs value. If there is no user specified compare_func then the return value from the function will be: atom value < comparison_rhs : negative integer atom value == comparison_rhs : zero atom value > comparison_rhs : positive integer If there IS a user specified compare_func then the return value is dependent on the internal implementation of that function. FAILURE: The return value of this function will be undefined with the errno set to an appropriate value on failure. Possible errno values are: EINVAL : The specified atom has not been initialized and it's synchronization mutex is invalid. **/ extern int sync_add_cmp( sync_int * atom, int modifier_rhs, int ( * compare_func ) ( int, int ), int compare_rhs ); extern int sync_sub_cmp( sync_int * atom, int modifier_rhs, int ( * compare_func ) ( int, int ), int compare_rhs ); extern int sync_mul_cmp( sync_int * atom, int modifier_rhs, int ( * compare_func ) ( int, int ), int compare_rhs ); extern int sync_div_cmp( sync_int * atom, int modifier_rhs, int ( * compare_func ) ( int, int ), int compare_rhs ); extern int sync_mod_cmp( sync_int * atom, int modifier_rhs, int ( * compare_func ) ( int, int ), int compare_rhs ); extern int sync_and_cmp( sync_int * atom, int modifier_rhs, int ( * compare_func ) ( int, int ), int compare_rhs ); extern int sync_or_cmp( sync_int * atom, int modifier_rhs, int ( * compare_func ) ( int, int ), int compare_rhs ); extern int sync_xor_cmp( sync_int * atom, int modifier_rhs, int ( * compare_func ) ( int, int ), int compare_rhs ); extern int sync_lshift_cmp( sync_int * atom, int modifier_rhs, int ( * compare_func ) ( int, int ), int compare_rhs ); extern int sync_rshift_cmp( sync_int * atom, int modifier_rhs, int ( * compare_func ) ( int, int ), int compare_rhs ); /** Function: sync_inc_exec sync_dec_exec sync_complement_exec sync_negate_exec Description: These functions will first atomically modify the value of the atom performing the operation described by the first token found after sync_ in the function name. If the exec_func parameter is non-NULL then the specified function is called with the arguments arg and the new value of the atom. Parameters: atom - a pointer to a previously intialized sync_int structure. exec_func - a pointer which if non-NULL is a user supplied function which will be executed after modification of the atom. arg - a pointer to user supplied arguments, possibly NULL, which will be passed to exec_func during execution. Return: SUCCESS: This function will return the atom's internal value AFTER the modification has been performed but PRIOR to the execution of any user specified function. FAILURE: The return value of this function will be undefined with the errno set to an appropriate value on failure. Possible errno values are: EINVAL : The specified atom has not been initialized and it's synchronization mutex is invalid. **/ extern int sync_inc_exec( sync_int * atom, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_dec_exec( sync_int * atom, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_complement_exec( sync_int * atom, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_negate_exec( sync_int * atom, void * ( * exec_func ) ( void *, int ), void * arg ); /** Function: Arithmetic Operation the User Function Execute sync_add_exec sync_sub_exec sync_mul_exec sync_div_exec sync_mod_exec Bitwise Operation then User Function Execute sync_and_exec sync_or_exec sync_xor_exec sync_lshift_exec sync_rshift_exec Description: These functions will atomically modify the internally held value of the atom by performing the operation described by the first token found after sync in the function name. The atom's value will be used as the left hand side and the value of modifier_rhs as the right hand side of the operation. If the exec_func parameter is non-NULL then the specified function is called with the arguments arg and the new value of the atom. Parameters: atom - a pointer to a previously intialized sync_int structure. modifier_rhs - the value to use as the rhs of the indicated operation. exec_func - a pointer which if non-NULL is a user supplied function which will be executed after modification of the atom. arg - a pointer to user supplied arguments, possibly NULL, which will be passed to exec_func during execution. Return: SUCCESS: This function will return the atom's internal value AFTER the modification has been performed but PRIOR to the execution of any user specified function. FAILURE: The return value of this function will be undefined with the errno set to an appropriate value on failure. Possible errno values are: EINVAL : The specified atom has not been initialized and it's synchronization mutex is invalid. **/ extern int sync_add_exec( sync_int * atom, int modifier_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_sub_exec( sync_int * atom, int modifier_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_mul_exec( sync_int * atom, int modifier_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_div_exec( sync_int * atom, int modifier_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_mod_exec( sync_int * atom, int modifier_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_and_exec( sync_int * atom, int modifier_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_or_exec( sync_int * atom, int modifier_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_xor_exec( sync_int * atom, int modifier_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_lshift_exec( sync_int * atom, int modifier_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_rshift_exec( sync_int * atom, int modifier_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); /** Function: sync_cmp_exec Description: This function will compare the atom's internal value to the specified compare_rhs value and calculate a value indicating the result of that comparison. If the compare_func parameter is NULL then the comparison will use the simple formula: result = atom->value - compare_rhs If the compare_func parameter is non-NULL is called and is performed by the specified function using the atom value as the left hand parameter and compare_rhs as the right hand parameter. If the result of the comparison operation is zero ( equal ) and the exec_func parameter is non-NULL then the specified exec_function is called with the arguments arg and the new value of the atom. Parameters: atom - a pointer to a previously intialized sync_int structure. compare_func - a pointer to a user supplied comparison function. If NULL then the default operation will be utlized. compare_rhs - the value to use as the right hand side of the comparison operation, whether it be the default implementation or user supplied function. exec_func - a pointer which if non-NULL is a user supplied function which will be executed after modification of the atom if the comparison operation returned zero. arg - a pointer to user supplied arguments, possibly NULL, which will be passed to exec_func during execution. Return: SUCCESS: The functions will return the value of the comparison operation between the atom's value and the comparison_rhs value. If there is no user specified compare_func then the return value from the function will be: atom value < comparison_rhs : negative integer atom value == comparison_rhs : zero atom value > comparison_rhs : positive integer If there IS a user specified compare_func then the return value is dependent on the internal implementation of that function. FAILURE: The return value of this function will be undefined with the errno set to an appropriate value on failure. Possible errno values are: EINVAL : The specified atom has not been initialized and it's synchronization mutex is invalid. **/ extern int sync_cmp_exec( sync_int * atom, int ( * compare_func ) ( int, int ), int compare_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); /** Function: sync_inc_cmp_exec sync_dec_cmp_exec sync_complement_cmp_exec sync_negate_cmp_exec Description: These functions will atomically modify the internally held values of the atom by performing the operation described by the second token of the function name. After that operation is complete, a comparison of the new value of the atom and compare_rhs value will be performed. If the compare_func parameter is NULL then the comparison will use the simple formula: result = atom->value - compare_rhs If the compare_func parameter is non-NULL is called and is performed by the specified function using the atom value as the left hand parameter and compare_rhs as the right hand parameter. If the result of the comparison operation is zero ( equal ) and the exec_func parameter is non-NULL then the specified exec_function is called with the arguments arg and the new value of the atom. Parameters: atom - a pointer to a previously intialized sync_int structure. compare_func - a pointer to a user supplied comparison function. If NULL then the default operation will be utlized. compare_rhs - the value to use as the right hand side of the comparison operation, whether it be the default implementation or user supplied function. exec_func - a pointer which if non-NULL is a user supplied function which will be executed after modification of the atom if the comparison operation returned a zero. arg - a pointer to user supplied arguments, possibly NULL, which will be passed to exec_func during execution. Return: SUCCESS: The functions will return the value of the comparison operation between the atom's value and the comparison_rhs value. If there is no user specified compare_func then the return value from the function will be: atom value < comparison_rhs : negative integer atom value == comparison_rhs : zero atom value > comparison_rhs : positive integer If there IS a user specified compare_func then the return value is dependent on the internal implementation of that function. FAILURE: The return value of this function will be undefined with the errno set to an appropriate value on failure. Possible errno values are: EINVAL : The specified atom has not been initialized and it's synchronization mutex is invalid. **/ extern int sync_inc_cmp_exec( sync_int * atom, int ( * compare_func ) ( int, int ), int compare_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_dec_cmp_exec( sync_int * atom, int ( * compare_func ) ( int, int ), int compare_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_complement_cmp_exec( sync_int * atom, int ( * compare_func ) ( int, int ), int compare_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_negate_cmp_exec( sync_int * atom, int ( * compare_func ) ( int, int ), int compare_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); /** Function: Arithmetic Op, Compare, Execute User Func on equal sync_add_cmp_exec sync_sub_cmp_exec sync_mul_cmp_exec sync_div_cmp_exec sync_mod_cmp_exec Bitwise Op, Compare, Execute User Func on equal sync_and_cmp_exec sync_or_cmp_exec sync_xor_cmp_exec sync_lshift_cmp_exec sync_rshift_cmp_exec Description: These functions will atomically modify the internally held values of the atom by performing the operation indicated by the second token of the function name. After that operation is complete, a comparison of the new value of the atom and compare_rhs value will be performed. If the compare_func parameter is NULL then the comparison will use the simple formula: result = atom->value - compare_rhs If the compare_func parameter is non-NULL is called and is performed by the specified function using the atom value as the left hand parameter and compare_rhs as the right hand parameter. If the result of the comparison operation is zero ( equal ) and the exec_func parameter is non-NULL then the specified exec_function is called with the arguments arg and the new value of the atom. Parameters: atom - a pointer to a previously intialized sync_int structure. modifier_rhs - the value to be used in the right hand of the indicated operation. compare_func - a pointer to a user supplied comparison function. If NULL then the default operation will be utlized. compare_rhs - the value to use as the right hand side of the comparison operation, whether it be the default implementation or user supplied function. exec_func - a pointer which if non-NULL is a user supplied function which will be executed after modification of the atom if the comparison operation returned a zero. arg - a pointer to user supplied arguments, possibly NULL, which will be passed to exec_func during execution. Return: SUCCESS: The functions will return the value of the comparison operation between the atom's value and the comparison_rhs value. If there is no user specified compare_func then the return value from the function will be: atom value < comparison_rhs : negative integer atom value == comparison_rhs : zero atom value > comparison_rhs : positive integer If there IS a user specified compare_func then the return value is dependent on the internal implementation of that function. FAILURE: The return value of this function will be undefined with the errno set to an appropriate value on failure. Possible errno values are: EINVAL : The specified atom has not been initialized and it's synchronization mutex is invalid. **/ extern int sync_add_cmp_exec( sync_int * atom, int modifier_rhs, int ( * compare_func ) ( int, int ), int compare_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_sub_cmp_exec( sync_int * atom, int modifier_rhs, int ( * compare_func ) ( int, int ), int compare_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_mul_cmp_exec( sync_int * atom, int modifier_rhs, int ( * compare_func ) ( int, int ), int compare_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_div_cmp_exec( sync_int * atom, int modifier_rhs, int ( * compare_func ) ( int, int ), int compare_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_mod_cmp_exec( sync_int * atom, int modifier_rhs, int ( * compare_func ) ( int, int ), int compare_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_and_cmp_exec( sync_int * atom, int modifier_rhs, int ( * compare_func ) ( int, int ), int compare_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_or_cmp_exec( sync_int * atom, int modifier_rhs, int ( * compare_func ) ( int, int ), int compare_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_xor_cmp_exec( sync_int * atom, int modifier_rhs, int ( * compare_func ) ( int, int ), int compare_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_lshift_cmp_exec( sync_int * atom, int modifier_rhs, int ( * compare_func ) ( int, int ), int compare_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_rshift_cmp_exec( sync_int * atom, int modifier_rhs, int ( * compare_func ) ( int, int ), int compare_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); /** Function: sync_inc_async_exec sync_dec_async_exec sync_complement_async_exec sync_negate_async_exec sync_add_async_exec sync_sub_async_exec sync_mul_async_exec sync_div_async_exec sync_mod_async_exec sync_and_async_exec sync_or_async_exec sync_xor_async_exec sync_lshift_async_exec sync_rshift_async_exec sync_cmp_async_exec sync_inc_cmp_async_exec sync_dec_cmp_async_exec sync_complement_cmp_async_exec sync_negate_cmp_async_exec sync_add_cmp_async_exec sync_sub_cmp_async_exec sync_mul_cmp_async_exec sync_div_cmp_async_exec sync_mod_cmp_async_exec sync_and_cmp_async_exec sync_or_cmp_async_exec sync_xor_cmp_async_exec sync_lshift_cmp_async_exec sync_rshift_cmp_async_exec Description: Descriptions of these functions may be found by looking at the descriptions of functions ending in "exec" where: sync_[XXX_]*exec sync_[XXX_]*async_exec The [XXX_]* components of the function names match. The primary difference between these function and normal exec is that the user supplied function, if any, is wrapped in a newly spawned thread and allowing it to execute asynchronously and the calling thread to return immediately. The spawned threads are DETACHED and it is the responsibility of the user supplied function to free any memory associated with the arg parameter if necessary. There is an addition errno of EAGAIN which can be returned by calls to these functions. Such an error condition indicates that the system lacked the resources required to spawn a new thread or that the process would cause the PTHREAD_THREADS_MAX limit to be exceeded. If this occurs, the user supplied function is NOT executed. **/ extern int sync_inc_async_exec( sync_int * atom, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_dec_async_exec( sync_int * atom, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_complement_async_exec( sync_int * atom, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_negate_async_exec( sync_int * atom, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_add_async_exec( sync_int * atom, int modifier_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_sub_async_exec( sync_int * atom, int modifier_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_mul_async_exec( sync_int * atom, int modifier_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_div_async_exec( sync_int * atom, int modifier_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_mod_async_exec( sync_int * atom, int modifier_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_and_async_exec( sync_int * atom, int modifier_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_or_async_exec( sync_int * atom, int modifier_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_xor_async_exec( sync_int * atom, int modifier_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_lshift_async_exec( sync_int * atom, int modifier_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_rshift_async_exec( sync_int * atom, int modifier_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_cmp_async_exec( sync_int * atom, int ( * compare_func ) ( int, int ), int compare_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_inc_cmp_async_exec( sync_int * atom, int ( * compare_func ) ( int, int ), int compare_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_dec_cmp_async_exec( sync_int * atom, int ( * compare_func ) ( int, int ), int compare_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_complement_cmp_async_exec( sync_int * atom, int ( * compare_func ) ( int, int ), int compare_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_negate_cmp_async_exec( sync_int * atom, int ( * compare_func ) ( int, int ), int compare_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_add_cmp_async_exec( sync_int * atom, int modifier_rhs, int ( * compare_func ) ( int, int ), int compare_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_sub_cmp_async_exec( sync_int * atom, int modifier_rhs, int ( * compare_func ) ( int, int ), int compare_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_mul_cmp_async_exec( sync_int * atom, int modifier_rhs, int ( * compare_func ) ( int, int ), int compare_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_div_cmp_async_exec( sync_int * atom, int modifier_rhs, int ( * compare_func ) ( int, int ), int compare_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_mod_cmp_async_exec( sync_int * atom, int modifier_rhs, int ( * compare_func ) ( int, int ), int compare_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_and_cmp_async_exec( sync_int * atom, int modifier_rhs, int ( * compare_func ) ( int, int ), int compare_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_or_cmp_async_exec( sync_int * atom, int modifier_rhs, int ( * compare_func ) ( int, int ), int compare_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_xor_cmp_async_exec( sync_int * atom, int modifier_rhs, int ( * compare_func ) ( int, int ), int compare_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_lshift_cmp_async_exec( sync_int * atom, int modifier_rhs, int ( * compare_func ) ( int, int ), int compare_rhs, void * ( * exec_func ) ( void *, int ), void * arg ); extern int sync_rshift_cmp_async_exec( sync_int * atom, int modifier_rhs, int ( * compare_func ) ( int, int ), int compare_rhs, void * ( * exec_func ) ( void *, int ), void * arg );