#ifndef ACL_ATOMIC_INCLUDE_H
#define ACL_ATOMIC_INCLUDE_H

#ifdef __cplusplus
extern "C"
{
#endif

#include "acl_define.h"

typedef struct ACL_ATOMIC ACL_ATOMIC;

/**
 * ԭӶ
 * @return {ACL_ATOMIC*} ´Ķ
 */
ACL_API ACL_ATOMIC *acl_atomic_new(void);

/**
 * ͷԭӶ
 * @param self {ACL_ATOMIC*} ԭӶ
 */
ACL_API void acl_atomic_free(ACL_ATOMIC *self);

/**
 * ָԭӶ󶨣ԱڶԸöԭӲ
 * @param self {ACL_ATOMIC*} ԭӶ
 * @param value {void*} ĶͨԭӶʵֶԸöԭӲ
 */
ACL_API void acl_atomic_set(ACL_ATOMIC *self, void *value);

/**
 * Ƚϲ󣬵ԭӶ󶨵ĶȽ϶ͬʱ¶
 * ֮ǰ󶨵Ķ
 * @param self {ACL_ATOMIC*} ԭӶ
 * @param cmp {void*} Ƚ϶ָ
 * @param value {void*} ԭӶȽ϶ͬʱὫöԭӶ
 * @return {void*} ԭӶ֮ǰ󶨵Ķ
 */
ACL_API void *acl_atomic_cas(ACL_ATOMIC *self, void *cmp, void *value);

/**
 * ԭӶ¶а󶨣֮ǰ󶨵Ķ
 * @param self {ACL_ATOMIC*} ԭӶ
 * @param value {void*} 󶨵¶
 * @return {void*} ֮ǰ󶨵Ķ
 */
ACL_API void *acl_atomic_xchg(ACL_ATOMIC *self, void *value);

/**
 *  acl_atomic_set 󶨵ĶΪֵʱԵô˺ñ󶨶
 * ĳֵ
 * @param self {ACL_ATOMIC*} ԭӶ
 * @param n {long long} ԭӶ󶨵Ķ󽫱ֵΪֵ
 */
ACL_API void acl_atomic_int64_set(ACL_ATOMIC *self, long long n);

/**
 * Ȼֵ洢ֵȻֵָ洢ڸֵ
 * @param self {ACL_ATOMIC*} ԭӶ
 * @param n {long long} ֵ 
 * @return {long long} ֮ǰֵֵ
 */
ACL_API long long acl_atomic_int64_fetch_add(ACL_ATOMIC *self, long long n);

/**
 * ݶ洢ֵֵָؽֵ
 * @param self {ACL_ATOMIC*} ԭӶ
 * @param n {long long} ֵ 
 * @return {long long} ֵ֮
 */
ACL_API long long acl_atomic_int64_add_fetch(ACL_ATOMIC *self, long long n);

/**
 * ȽϲֵԭӶ洢ֵȽֵͬʱ
 * ֵҷ֮ǰ洢ֵ
 * @param self {ACL_ATOMIC*} ԭӶ
 * @param cmp {long long} Ƚֵ
 * @param n {long long} ԭӶȽֵͬʱὫԭӶΪֵ
 * @return {long long} ԭӶ֮ǰ洢ֵ
 */
ACL_API long long acl_atomic_int64_cas(ACL_ATOMIC *self, long long cmp, long long n);

/****************************************************************************/

typedef struct ACL_ATOMIC_CLOCK ACL_ATOMIC_CLOCK;

ACL_API ACL_ATOMIC_CLOCK *acl_atomic_clock_alloc(void);
ACL_API void acl_atomic_clock_free(ACL_ATOMIC_CLOCK *clk);
ACL_API long long acl_atomic_clock_count_add(ACL_ATOMIC_CLOCK *clk, int n);
ACL_API long long acl_atomic_clock_users_add(ACL_ATOMIC_CLOCK *clk, int n);
ACL_API void acl_atomic_clock_users_count_inc(ACL_ATOMIC_CLOCK *clk);
ACL_API long long acl_atomic_clock_count(ACL_ATOMIC_CLOCK *clk);
ACL_API long long acl_atomic_clock_atime(ACL_ATOMIC_CLOCK *clk);
ACL_API long long acl_atomic_clock_users(ACL_ATOMIC_CLOCK *clk);

#ifdef __cplusplus
}
#endif

#endif
