105 lines
2.5 KiB
C
105 lines
2.5 KiB
C
|
|
#ifndef _OS_ATOMIC_H_
|
|
#define _OS_ATOMIC_H_
|
|
#include "typesdef.h"
|
|
#include "osal/irq.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
typedef struct {
|
|
uint8 counter;
|
|
} atomic8_t;
|
|
|
|
typedef struct {
|
|
uint16 counter;
|
|
} atomic16_t;
|
|
|
|
typedef struct {
|
|
uint32 counter;
|
|
} atomic_t;
|
|
|
|
typedef struct {
|
|
uint64 counter;
|
|
} atomic64_t;
|
|
|
|
|
|
#define atomic64_read(v) ((v)->counter)
|
|
#define atomic_read(v) ((v)->counter)
|
|
|
|
#define atomic_set(v,i) ({ \
|
|
uint32 __mask__ = disable_irq();\
|
|
((v)->counter = i); \
|
|
enable_irq(__mask__);\
|
|
})
|
|
#define atomic_add(v,i) ({ \
|
|
uint32 __mask__ = disable_irq();\
|
|
((v)->counter += i); \
|
|
enable_irq(__mask__);\
|
|
})
|
|
#define atomic_sub(v,i) ({ \
|
|
uint32 __mask__ = disable_irq();\
|
|
if((v)->counter > (i)) { ((v)->counter -= (i)); }\
|
|
else { (v)->counter = 0; }\
|
|
enable_irq(__mask__);\
|
|
})
|
|
#define atomic_inc(v) ({ \
|
|
uint32 __mask__ = disable_irq();\
|
|
((v)->counter++); \
|
|
enable_irq(__mask__);\
|
|
})
|
|
#define atomic_dec(v) ({ \
|
|
uint32 __mask__ = disable_irq();\
|
|
if((v)->counter > 0){ (v)->counter--; }\
|
|
enable_irq(__mask__);\
|
|
})
|
|
#define atomic_inc_return(v) ({\
|
|
uint32 __mask__ = disable_irq();\
|
|
uint32_t __val__ = (++(v)->counter);\
|
|
enable_irq(__mask__);\
|
|
__val__;\
|
|
})
|
|
#define atomic_dec_return(v) ({\
|
|
uint32 __mask__ = disable_irq();\
|
|
uint32_t __val__ = ((v)->counter > 0) ? (--(v)->counter) : 0;\
|
|
enable_irq(__mask__);\
|
|
__val__;\
|
|
})
|
|
#define atomic_dec2_return(v) ({\
|
|
uint32 __mask__ = disable_irq();\
|
|
uint32_t __val__ = (v)->counter;\
|
|
if((v)->counter) (--(v)->counter);\
|
|
enable_irq(__mask__);\
|
|
__val__;\
|
|
})
|
|
#define atomic_dec_and_test(v) ({\
|
|
uint32 __mask__ = disable_irq();\
|
|
uint32_t __val__ = ((v)->counter > 0) ? ((--(v)->counter) == 0) : 1;\
|
|
enable_irq(__mask__);\
|
|
__val__;\
|
|
})
|
|
#define atomic_cmpxchg(v,o,n) ({\
|
|
uint32 __mask__ = disable_irq();\
|
|
uint32_t __val = (v)->counter;\
|
|
if(__val == o) { (v)->counter = n; }\
|
|
enable_irq(__mask__);\
|
|
__val;\
|
|
})
|
|
|
|
static inline int atomic_add_unless(atomic_t *v, int a, int u)
|
|
{
|
|
int c, old;
|
|
c = atomic_read(v);
|
|
while (c != u && (old = atomic_cmpxchg((v), c, c + a)) != c) {
|
|
c = old;
|
|
}
|
|
return c != u;
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|