implement atomic bitfield ops

pull/81/head
Richard Fuchs 11 years ago
parent 91a85e6cd8
commit 6173a7a2dc

@ -474,34 +474,40 @@ INLINE int family_from_address(const struct in6_addr *a) {
}
/* checks if at least one of the flags is set */
INLINE int bf_isset(const unsigned int *u, unsigned int f) {
if ((*u & f))
INLINE int bf_isset(const volatile unsigned int *u, unsigned int f) {
if ((g_atomic_int_get(u) & f))
return -1;
return 0;
}
INLINE void bf_set(unsigned int *u, unsigned int f) {
*u |= f;
INLINE void bf_set(volatile unsigned int *u, unsigned int f) {
g_atomic_int_or(u, f);
}
INLINE void bf_clear(unsigned int *u, unsigned int f) {
*u &= ~f;
INLINE void bf_clear(volatile unsigned int *u, unsigned int f) {
g_atomic_int_and(u, ~f);
}
INLINE void bf_xset(unsigned int *u, unsigned int f, int cond) {
bf_clear(u, f);
bf_set(u, cond ? f : 0);
INLINE void bf_set_clear(volatile unsigned int *u, unsigned int f, int cond) {
if (cond)
bf_set(u, f);
else
bf_clear(u, f);
}
/* works only for single flags */
INLINE void bf_copy(unsigned int *u, unsigned int f, const unsigned int *s, unsigned int g) {
/* a good compiler will optimize out the calls to log2() */
*u &= ~f;
if (f >= g)
*u |= (*s & g) << (int) (log2(f) - log2(g));
else
*u |= (*s & g) >> (int) (log2(g) - log2(f));
INLINE void bf_copy(volatile unsigned int *u, unsigned int f,
const volatile unsigned int *s, unsigned int g)
{
bf_set_clear(u, f, bf_isset(s, g));
}
/* works for multiple flags */
INLINE void bf_copy_same(unsigned int *u, const unsigned int *s, unsigned int g) {
bf_copy(u, g, s, g);
INLINE void bf_copy_same(volatile unsigned int *u, const volatile unsigned int *s, unsigned int g) {
unsigned int old, set, clear;
old = g_atomic_int_get(s);
set = old & g;
clear = ~old & g;
bf_set(u, set);
bf_clear(u, clear);
}
INLINE void g_queue_append(GQueue *dst, const GQueue *src) {
GList *l;
if (!src || !dst)

@ -303,8 +303,7 @@ struct packet_stream {
X509 *dtls_cert; /* LOCK: in_lock */
/* in_lock must be held for SETTING these: */
/* (XXX replace with atomic ops where appropriate) */
unsigned int ps_flags;
volatile unsigned int ps_flags;
};
/* protected by call->master_lock, except the RO elements */
@ -337,7 +336,7 @@ struct call_media {
GSList *endpoint_maps;
GHashTable *rtp_payload_types;
unsigned int media_flags;
volatile unsigned int media_flags;
};
/* half a dialogue */

@ -1123,9 +1123,9 @@ int sdp_streams(const GQueue *sessions, GQueue *streams, struct sdp_ng_flags *fl
sp->type = media->media_type;
memcpy(sp->direction, flags->direction, sizeof(sp->direction));
sp->desired_family = flags->address_family;
bf_xset(&sp->sp_flags, SP_FLAG_ASYMMETRIC, flags->asymmetric);
bf_xset(&sp->sp_flags, SP_FLAG_STRICT_SOURCE, flags->strict_source);
bf_xset(&sp->sp_flags, SP_FLAG_MEDIA_HANDOVER, flags->media_handover);
bf_set_clear(&sp->sp_flags, SP_FLAG_ASYMMETRIC, flags->asymmetric);
bf_set_clear(&sp->sp_flags, SP_FLAG_STRICT_SOURCE, flags->strict_source);
bf_set_clear(&sp->sp_flags, SP_FLAG_MEDIA_HANDOVER, flags->media_handover);
errstr = "Invalid RTP payload types";
if (__rtp_payload_types(sp, media))

Loading…
Cancel
Save