#define SvFLAGS(sv) (sv)->sv_flags
#define SvREFCNT(sv) (sv)->sv_refcnt
+#ifdef USE_THREADS
+
+# ifndef EMULATE_ATOMIC_REFCOUNTS
+# include "atomic.h"
+# endif
+
+# ifdef EMULATE_ATOMIC_REFCOUNTS
+# define ATOMIC_INC(count) STMT_START { \
+ MUTEX_LOCK(&svref_mutex); \
+ ++count; \
+ MUTEX_UNLOCK(&svref_mutex); \
+ } STMT_END
+# define ATOMIC_DEC_AND_TEST(res,count) STMT_START { \
+ MUTEX_LOCK(&svref_mutex); \
+ res = (--count == 0); \
+ MUTEX_UNLOCK(&svref_mutex); \
+ } STMT_END
+# else
+# define ATOMIC_INC(count) atomic_inc(&count)
+# define ATOMIC_DEC_AND_TEST(res,count) (res = atomic_dec_and_test(&count))
+# endif /* EMULATE_ATOMIC_REFCOUNTS */
+#else
+# define ATOMIC_INC(count) (++count)
+# define ATOMIC_DEC_AND_TEST(res, count) (res = (--count == 0))
+#endif /* USE_THREADS */
+
#ifdef __GNUC__
-# define SvREFCNT_inc(sv) ({SV* nsv=(SV*)(sv); if(nsv) ++SvREFCNT(nsv); nsv;})
+# define SvREFCNT_inc(sv) \
+ ({ \
+ SV *nsv = (SV*)(sv); \
+ if (nsv) \
+ ATOMIC_INC(SvREFCNT(nsv)); \
+ nsv; \
+ })
#else
# if defined(CRIPPLED_CC) || defined(USE_THREADS)
# define SvREFCNT_inc(sv) sv_newref((SV*)sv)
# else
-# define SvREFCNT_inc(sv) ((Sv=(SV*)(sv)), (Sv && ++SvREFCNT(Sv)), (SV*)Sv)
+# define SvREFCNT_inc(sv) \
+ ((Sv=(SV*)(sv)), (Sv && ATOMIC_INC(SvREFCNT(Sv))), (SV*)Sv)
# endif
#endif
double xnv_nv; /* numeric value, if any */
};
+/* These structure must match the beginning of struct xpvhv in hv.h. */
struct xpvmg {
char * xpv_pv; /* pointer to malloced string */
STRLEN xpv_cur; /* length of xpv_pv as a C string */
# endif
#endif /* __GNUC__ */
-/* the following macros updates any magic values this sv is associated with */
+/* the following macros update any magic values this sv is associated with */
#define SvGETMAGIC(x) STMT_START { if (SvGMAGICAL(x)) mg_get(x); } STMT_END
#define SvSETMAGIC(x) STMT_START { if (SvSMAGICAL(x)) mg_set(x); } STMT_END
#define SvSetMagicSV_nosteal(dst,src) \
SvSetSV_nosteal_and(dst,src,SvSETMAGIC(dst))
-#define SvSetMagicPV(dst,s) \
- STMT_START { sv_setpv(dst,s); SvSETMAGIC(dst); } STMT_END
-#define SvSetMagicPVN(dst,s,l) \
- STMT_START { sv_setpvn(dst,s,l); SvSETMAGIC(dst); } STMT_END
-#define SvSetMagicIV(dst,i) \
- STMT_START { sv_setiv(dst,i); SvSETMAGIC(dst); } STMT_END
-#define SvSetMagicPVIV(dst,i) \
- STMT_START { sv_setpviv(dst,i); SvSETMAGIC(dst); } STMT_END
-#define SvSetMagicUV(dst,u) \
- STMT_START { sv_setuv(dst,u); SvSETMAGIC(dst); } STMT_END
-#define SvSetMagicNV(dst,n) \
- STMT_START { sv_setnv(dst,n); SvSETMAGIC(dst); } STMT_END
-#define SvCatMagicPV(dst,s) \
- STMT_START { sv_catpv(dst,s); SvSETMAGIC(dst); } STMT_END
-#define SvCatMagicPVN(dst,s,l) \
- STMT_START { sv_catpvn(dst,s,l); SvSETMAGIC(dst); } STMT_END
-#define SvCatMagicSV(dst,src) \
- STMT_START { sv_catsv(dst,src); SvSETMAGIC(dst); } STMT_END
-#define SvUseMagicPVN(dst,s,l) \
- STMT_START { sv_usepvn(dst,s,l); SvSETMAGIC(dst); } STMT_END
-
#define SvPEEK(sv) sv_peek(sv)
#define SvIMMORTAL(sv) ((sv)==&sv_undef || (sv)==&sv_yes || (sv)==&sv_no)