SILC Runtime Toolkit 1.2 Beta 1
[runtime.git] / lib / silcutil / silcatomic.h
index e2719b4c62a537d59310f8613790ea46a78217fb..a6cb2b51bdc919c6409a2ae1313012580f249f1c 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2006 - 2007 Pekka Riikonen
+  Copyright (C) 2006 - 2008 Pekka Riikonen
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -17,7 +17,7 @@
 
 */
 
-/****h* silcutil/SILC Atomic Operations Interface
+/****h* silcutil/Atomic Operations Interface
  *
  * DESCRIPTION
  *
  *
  * Fast operations are supported on: x86, x86_64, ia64, PPC
  *
+ * EXAMPLE
+ *
+ * SilcAtomic32 refcnt;
+ *
+ * // Initialize atomic variable
+ * silc_atomic_init32(&refcnt, 0);
+ *
+ * // Increment referene counter by one
+ * silc_atomic_add_int32(&refcnt, 1);
+ *
+ * // Uninitialize atomic variable
+ * silc_atomic_uninit32(&refcnt);
+ *
  ***/
 
 #ifndef SILCATOMIC_H
 #define SILCATOMIC_H
 
-/* For now we always assume SMP */
-#define SILC_SMP 1
-
 /* Use lock prefix only on true SMP systems */
 #ifdef SILC_SMP
 #define SILC_SMP_LOCK "lock; "
@@ -50,7 +60,7 @@
 #define SILC_SMP_LOCK
 #endif /* SILC_SMP */
 
-/****s* silcutil/SilcAtomicAPI/SilcAtomic32
+/****s* silcutil/SilcAtomic32
  *
  * NAME
  *
@@ -78,7 +88,7 @@
  *
  ***/
 
-/****s* silcutil/SilcAtomicAPI/SilcAtomic16
+/****s* silcutil/SilcAtomic16
  *
  * NAME
  *
  *
  ***/
 
-/****s* silcutil/SilcAtomicAPI/SilcAtomic8
+/****s* silcutil/SilcAtomic8
  *
  * NAME
  *
  *
  ***/
 
-/****s* silcutil/SilcAtomicAPI/SilcAtomicPointer
+/****s* silcutil/SilcAtomicPointer
  *
  * NAME
  *
     (defined(SILC_I486) || defined(SILC_X86_64) || defined(SILC_IA64) ||    \
      defined(SILC_POWERPC)))
 typedef struct {
-  volatile SilcUInt32 value;
+  SilcUInt32 value;
 } SilcAtomic32;
 typedef struct {
-  volatile void *value;
+  void *value;
 } SilcAtomicPointer;
 #else
 #define SILC_ATOMIC_MUTEX
 typedef struct {
   SilcMutex lock;
-  volatile SilcUInt32 value;
+  SilcUInt32 value;
 } SilcAtomic32;
 typedef struct {
   SilcMutex lock;
-  volatile void *value;
+  void *value;
 } SilcAtomicPointer;
 #endif
 
 #if !defined(SILC_THREADS) || (defined(__GNUC__) && (defined(SILC_I486) ||  \
                                                     defined(SILC_X86_64)))
 typedef struct {
-  volatile SilcUInt16 value;
+  SilcUInt16 value;
 } SilcAtomic16;
 #elif defined(SILC_WIN32) || (defined(__GNUC__) && (defined(SILC_IA64) ||   \
                                                    defined(SILC_POWERPC)))
 typedef struct {
-  volatile SilcUInt32 value;
+  SilcUInt32 value;
 } SilcAtomic16;
 #else
 typedef struct {
   SilcMutex lock;
-  volatile SilcUInt16 value;
+  SilcUInt16 value;
 } SilcAtomic16;
 #endif
 
 #if !defined(SILC_THREADS) || (defined(__GNUC__) && (defined(SILC_I486) ||  \
                                                     defined(SILC_X86_64)))
 typedef struct {
-  volatile SilcUInt8 value;
+  SilcUInt8 value;
 } SilcAtomic8;
 #elif defined(SILC_WIN32) || (defined(__GNUC__) && (defined(SILC_IA64) ||   \
                                                    defined(SILC_POWERPC)))
 typedef struct {
-  volatile SilcUInt32 value;
+  SilcUInt32 value;
 } SilcAtomic8;
 #else
 typedef struct {
   SilcMutex lock;
-  volatile SilcUInt8 value;
+  SilcUInt8 value;
 } SilcAtomic8;
 #endif
 
-/****f* silcutil/SilcAtomicAPI/silc_atomic_init32
+/****f* silcutil/silc_atomic_init32
  *
  * SYNOPSIS
  *
@@ -232,7 +242,7 @@ typedef struct {
  *
  ***/
 
-/****f* silcutil/SilcAtomicAPI/silc_atomic_init16
+/****f* silcutil/silc_atomic_init16
  *
  * SYNOPSIS
  *
@@ -247,7 +257,7 @@ typedef struct {
  *
  ***/
 
-/****f* silcutil/SilcAtomicAPI/silc_atomic_init8
+/****f* silcutil/silc_atomic_init8
  *
  * SYNOPSIS
  *
@@ -262,7 +272,7 @@ typedef struct {
  *
  ***/
 
-/****f* silcutil/SilcAtomicAPI/silc_atomic_init_pointer
+/****f* silcutil/silc_atomic_init_pointer
  *
  * SYNOPSIS
  *
@@ -286,24 +296,24 @@ SilcBool silc_atomic_init##name(SilcAtomic##bits *atomic, type value)
 #define SILC_ATOMIC_INIT(name, bits, type)                             \
 SILC_ATOMIC_INIT_F(name, bits, type)                                   \
 {                                                                      \
-  atomic->value = value;                                               \
+  *(type volatile *)&atomic->value = value;                            \
   return silc_mutex_alloc(&atomic->lock);                              \
 }
 #else
 #define SILC_ATOMIC_INIT(name, bits, type)                             \
 SILC_ATOMIC_INIT_F(name, bits, type)                                   \
 {                                                                      \
-  atomic->value = value;                                               \
+  *(type volatile *)&atomic->value = value;                            \
   return TRUE;                                                         \
 }
 #endif /* SILC_ATOMIC_MUTEX */
 
-SILC_ATOMIC_INIT(8, 8, SilcUInt8);
-SILC_ATOMIC_INIT(16, 16, SilcUInt16);
-SILC_ATOMIC_INIT(32, 32, SilcUInt32);
-SILC_ATOMIC_INIT(_pointer, Pointer, void *);
+SILC_ATOMIC_INIT(8, 8, SilcUInt8)
+SILC_ATOMIC_INIT(16, 16, SilcUInt16)
+SILC_ATOMIC_INIT(32, 32, SilcUInt32)
+SILC_ATOMIC_INIT(_pointer, Pointer, void *)
 
-/****f* silcutil/SilcAtomicAPI/silc_atomic_uninit32
+/****f* silcutil/silc_atomic_uninit32
  *
  * SYNOPSIS
  *
@@ -317,7 +327,7 @@ SILC_ATOMIC_INIT(_pointer, Pointer, void *);
  *
  ***/
 
-/****f* silcutil/SilcAtomicAPI/silc_atomic_uninit16
+/****f* silcutil/silc_atomic_uninit16
  *
  * SYNOPSIS
  *
@@ -331,7 +341,7 @@ SILC_ATOMIC_INIT(_pointer, Pointer, void *);
  *
  ***/
 
-/****f* silcutil/SilcAtomicAPI/silc_atomic_uninit8
+/****f* silcutil/silc_atomic_uninit8
  *
  * SYNOPSIS
  *
@@ -345,7 +355,7 @@ SILC_ATOMIC_INIT(_pointer, Pointer, void *);
  *
  ***/
 
-/****f* silcutil/SilcAtomicAPI/silc_atomic_uninit_pointer
+/****f* silcutil/silc_atomic_uninit_pointer
  *
  * SYNOPSIS
  *
@@ -372,15 +382,16 @@ SILC_ATOMIC_UNINIT_F(bits, t)                                             \
 #define SILC_ATOMIC_UNINIT(bits, t)                                    \
 SILC_ATOMIC_UNINIT_F(bits, t)                                          \
 {                                                                      \
+  memset(atomic, 0, sizeof(*atomic));                                  \
 }
 #endif /* SILC_ATOMIC_MUTEX */
 
-SILC_ATOMIC_UNINIT(8, 8);
-SILC_ATOMIC_UNINIT(16, 16);
-SILC_ATOMIC_UNINIT(32, 32);
-SILC_ATOMIC_UNINIT(_pointer, Pointer);
+SILC_ATOMIC_UNINIT(8, 8)
+SILC_ATOMIC_UNINIT(16, 16)
+SILC_ATOMIC_UNINIT(32, 32)
+SILC_ATOMIC_UNINIT(_pointer, Pointer)
 
-/****f* silcutil/SilcAtomicAPI/silc_atomic_set_int32
+/****f* silcutil/silc_atomic_set_int32
  *
  * SYNOPSIS
  *
@@ -393,7 +404,7 @@ SILC_ATOMIC_UNINIT(_pointer, Pointer);
  *
  ***/
 
-/****f* silcutil/SilcAtomicAPI/silc_atomic_set_int16
+/****f* silcutil/silc_atomic_set_int16
  *
  * SYNOPSIS
  *
@@ -406,7 +417,7 @@ SILC_ATOMIC_UNINIT(_pointer, Pointer);
  *
  ***/
 
-/****f* silcutil/SilcAtomicAPI/silc_atomic_set_int8
+/****f* silcutil/silc_atomic_set_int8
  *
  * SYNOPSIS
  *
@@ -436,7 +447,7 @@ SILC_ATOMIC_SET_INT_F(bits)                                         \
 SILC_ATOMIC_SET_INT_F(bits)                                            \
 {                                                                      \
   /* Windows */                                                                \
-  InterlockedExchange((LONG)&atomic->value, (LONG)value);              \
+  InterlockedExchange((LONG *)&atomic->value, (LONG)value);            \
 }
 
 #elif defined(__GNUC__) && (defined(SILC_I486) || defined(SILC_X86_64))
@@ -454,7 +465,7 @@ SILC_ATOMIC_SET_INT_F(bits)                                         \
 SILC_ATOMIC_SET_INT_F(bits)                                            \
 {                                                                      \
   /* IA64, memory barrier needed */                                    \
-  atomic->value = value;                                               \
+  *(volatile SilcUInt##bits *)&atomic->value = value;                  \
   __sync_synchronize();                                                        \
 }
 
@@ -463,7 +474,7 @@ SILC_ATOMIC_SET_INT_F(bits)                                         \
 SILC_ATOMIC_SET_INT_F(bits)                                            \
 {                                                                      \
   /* PowerPC, memory barrier needed */                                 \
-  atomic->value = value;                                               \
+  *(volatile SilcUInt##bits *)&atomic->value = &value;                 \
   __asm("sync" : : : "memory");                                                \
 }
 
@@ -478,11 +489,11 @@ SILC_ATOMIC_SET_INT_F(bits)                                               \
 }
 #endif /* !SILC_THREADS */
 
-SILC_ATOMIC_SET_INT(8, "b", "b");
-SILC_ATOMIC_SET_INT(16, "w", "w");
-SILC_ATOMIC_SET_INT(32, "l", "");
+SILC_ATOMIC_SET_INT(8, "b", "b")
+SILC_ATOMIC_SET_INT(16, "w", "w")
+SILC_ATOMIC_SET_INT(32, "l", "")
 
-/****f* silcutil/SilcAtomicAPI/silc_atomic_set_pointer
+/****f* silcutil/silc_atomic_set_pointer
  *
  * SYNOPSIS
  *
@@ -501,19 +512,19 @@ void silc_atomic_set_pointer(SilcAtomicPointer *atomic, void *pointer)
 #if !defined(SILC_THREADS) ||                   \
      (defined(__GNUC__) && (defined(SILC_I486) || defined(SILC_X86_64)))
   /* No threads, Windows, i486 or x86_64, no memory barrier needed */
-  atomic->value = pointer;
+  *(void * volatile *)&atomic->value = pointer;
 
 #elif defined(SILC_WIN32)
   InterlockedExchangePointer(&atomic->value, pointer);
 
 #elif defined(__GNUC__) && defined(SILC_IA64)
   /* IA64, memory barrier needed */
-  atomic->value = pointer;
+  *(void * volatile *)&atomic->value = pointer;
   __sync_synchronize();
 
 #elif defined(__GNUC__) && defined(SILC_POWERPC)
   /* PowerPC, memory barrier needed */
-  atomic->value = pointer;
+  *(void * volatile *)&atomic->value = pointer;
   __asm("sync" : : : "memory");
 
 #else
@@ -524,7 +535,7 @@ void silc_atomic_set_pointer(SilcAtomicPointer *atomic, void *pointer)
 #endif
 }
 
-/****f* silcutil/SilcAtomicAPI/silc_atomic_get_int32
+/****f* silcutil/silc_atomic_get_int32
  *
  * SYNOPSIS
  *
@@ -537,7 +548,7 @@ void silc_atomic_set_pointer(SilcAtomicPointer *atomic, void *pointer)
  *
  ***/
 
-/****f* silcutil/SilcAtomicAPI/silc_atomic_get_int16
+/****f* silcutil/silc_atomic_get_int16
  *
  * SYNOPSIS
  *
@@ -550,7 +561,7 @@ void silc_atomic_set_pointer(SilcAtomicPointer *atomic, void *pointer)
  *
  ***/
 
-/****f* silcutil/SilcAtomicAPI/silc_atomic_get_int8
+/****f* silcutil/silc_atomic_get_int8
  *
  * SYNOPSIS
  *
@@ -575,7 +586,7 @@ SILC_ATOMIC_GET_INT_F(bits)                                         \
   SilcUInt##bits ret;                                                  \
                                                                        \
   /* No threads, Windows, i486 or x86_64, no memory barrier needed */  \
-  ret = atomic->value;                                                 \
+  ret = *(volatile SilcUInt##bits *)&atomic->value;                    \
   return ret;                                                          \
 }
 
@@ -587,7 +598,7 @@ SILC_ATOMIC_GET_INT_F(bits)                                         \
                                                                        \
   /* IA64, memory barrier needed */                                    \
   __sync_synchronize();                                                        \
-  ret = atomic->value;                                                 \
+  ret = *(volatile SilcUInt##bits *)&atomic->value;                    \
   return ret;                                                          \
 }
 
@@ -599,7 +610,7 @@ SILC_ATOMIC_GET_INT_F(bits)                                         \
                                                                        \
   /* PowerPC, memory barrier needed */                                 \
   __asm("sync" : : : "memory");                                                \
-  ret = atomic->value;                                                 \
+  ret = *(volatile SilcUInt##bits *)&atomic->value;                    \
   return ret;                                                          \
 }
 
@@ -617,11 +628,11 @@ SILC_ATOMIC_GET_INT_F(bits)                                               \
 }
 #endif /* !SILC_THREADS */
 
-SILC_ATOMIC_GET_INT(8);
-SILC_ATOMIC_GET_INT(16);
-SILC_ATOMIC_GET_INT(32);
+SILC_ATOMIC_GET_INT(8)
+SILC_ATOMIC_GET_INT(16)
+SILC_ATOMIC_GET_INT(32)
 
-/****f* silcutil/SilcAtomicAPI/silc_atomic_get_pointer
+/****f* silcutil/silc_atomic_get_pointer
  *
  * SYNOPSIS
  *
@@ -642,19 +653,19 @@ void *silc_atomic_get_pointer(SilcAtomicPointer *atomic)
 #if !defined(SILC_THREADS) || defined(SILC_WIN32) ||                    \
      (defined(__GNUC__) && (defined(SILC_I486) || defined(SILC_X86_64)))
   /* No threads, Windows, i486 or x86_64, no memory barrier needed */
-  ret = (void *)atomic->value;
+  ret = (void *)*(void * volatile *)&atomic->value;
   return ret;
 
 #elif defined(__GNUC__) && defined(SILC_IA64)
   /* IA64, memory barrier needed */
   __sync_synchronize();
-  ret = (void *)atomic->value;
+  ret = (void *)*(void * volatile *)&atomic->value;
   return ret;
 
 #elif defined(__GNUC__) && defined(SILC_POWERPC)
   /* PowerPC, memory barrier needed */
   __asm("sync" : : : "memory");
-  ret = (void *)atomic->value;
+  ret = (void *)*(void * volatile *)&atomic->value;
   return ret;
 
 #else
@@ -666,7 +677,7 @@ void *silc_atomic_get_pointer(SilcAtomicPointer *atomic)
 #endif
 }
 
-/****f* silcutil/SilcAtomicAPI/silc_atomic_add_int32
+/****f* silcutil/silc_atomic_add_int32
  *
  * SYNOPSIS
  *
@@ -680,7 +691,7 @@ void *silc_atomic_get_pointer(SilcAtomicPointer *atomic)
  *
  ***/
 
-/****f* silcutil/SilcAtomicAPI/silc_atomic_add_int32
+/****f* silcutil/silc_atomic_add_int16
  *
  * SYNOPSIS
  *
@@ -694,7 +705,7 @@ void *silc_atomic_get_pointer(SilcAtomicPointer *atomic)
  *
  ***/
 
-/****f* silcutil/SilcAtomicAPI/silc_atomic_add_int8
+/****f* silcutil/silc_atomic_add_int8
  *
  * SYNOPSIS
  *
@@ -719,8 +730,8 @@ SILC_ATOMIC_ADD_INT_F(bits)                                         \
 {                                                                      \
   SilcUInt##bits ret;                                                  \
   /* No atomic operations */                                           \
-  ret = atomic->value;                                                 \
-  atomic->value += value;                                              \
+  ret = *(volatile SilcUInt##bits *)&atomic->value;                    \
+  *(volatile SilcUInt##bits *)&atomic->value += value;                 \
   return ret + value;                                                  \
 }
 
@@ -731,7 +742,8 @@ SILC_ATOMIC_ADD_INT_F(bits)                                         \
   SilcUInt##bits ret;                                                  \
   LONG val = value;                                                    \
   /* Windows */                                                                \
-  ret = InterlockedExchangeAdd(&atomic->value, val);                   \
+  ret = InterlockedExchangeAdd((volatile SilcUInt##bits *)&atomic->value, \
+                              val);                                    \
   return ret + value;                                                  \
 }
 
@@ -742,8 +754,7 @@ SILC_ATOMIC_ADD_INT_F(bits)                                         \
   SilcUInt##bits ret;                                                  \
   /* GCC + i486 or x86_64 */                                           \
   __asm __volatile(SILC_SMP_LOCK "xadd" bp " %0, %1"                   \
-                  : "=r" (ret), "+m" (atomic->value)                   \
-                  : "0" (value));                                      \
+                  : "=r" (ret), "+m" (atomic->value) : "0" (value));   \
   return ret + value;                                                  \
 }
 
@@ -752,9 +763,9 @@ SILC_ATOMIC_ADD_INT_F(bits)                                         \
 SILC_ATOMIC_ADD_INT_F(bits)                                            \
 {                                                                      \
   SilcUInt##bits ret;                                                  \
-  SilcInt32 val = value;
+  SilcUInt32 val = value;                                              \
   /* GCC + IA64 (GCC builtin atomic operations) */                     \
-  ret = __sync_fetch_and_add(&atomic->value, val);                     \
+  ret = __sync_fetch_and_add((volatile SilcUInt32 *)&atomic->value, val); \
   return ret + value;                                                  \
 }
 
@@ -763,7 +774,7 @@ SILC_ATOMIC_ADD_INT_F(bits)                                         \
 SILC_ATOMIC_ADD_INT_F(bits)                                            \
 {                                                                      \
   SilcUInt32 ret;                                                      \
-  SilcInt32 val = value;                                               \
+  SilcUInt32 val = value;                                              \
   /* GCC + PowerPC (code adapted from IBM's documentation) */          \
   __asm __volatile("0: lwarx  %0,  0, %2\n"                            \
                   "   add    %0, %1, %0\n"                             \
@@ -789,11 +800,11 @@ SILC_ATOMIC_ADD_INT_F(bits)                                               \
 }
 #endif /* !SILC_THREADS */
 
-SILC_ATOMIC_ADD_INT(8, "b");
-SILC_ATOMIC_ADD_INT(16, "w");
-SILC_ATOMIC_ADD_INT(32, "l");
+SILC_ATOMIC_ADD_INT(8, "b")
+SILC_ATOMIC_ADD_INT(16, "w")
+SILC_ATOMIC_ADD_INT(32, "l")
 
-/****f* silcutil/SilcAtomicAPI/silc_atomic_sub_int32
+/****f* silcutil/silc_atomic_sub_int32
  *
  * SYNOPSIS
  *
@@ -807,7 +818,7 @@ SILC_ATOMIC_ADD_INT(32, "l");
  *
  ***/
 
-/****f* silcutil/SilcAtomicAPI/silc_atomic_sub_int16
+/****f* silcutil/silc_atomic_sub_int16
  *
  * SYNOPSIS
  *
@@ -821,7 +832,7 @@ SILC_ATOMIC_ADD_INT(32, "l");
  *
  ***/
 
-/****f* silcutil/SilcAtomicAPI/silc_atomic_sub_int8
+/****f* silcutil/silc_atomic_sub_int8
  *
  * SYNOPSIS
  *
@@ -839,7 +850,7 @@ SILC_ATOMIC_ADD_INT(32, "l");
 #define silc_atomic_sub_int16(a, v) silc_atomic_add_int16(a, (-v))
 #define silc_atomic_sub_int32(a, v) silc_atomic_add_int32(a, (-v))
 
-/****f* silcutil/SilcAtomicAPI/silc_atomic_inc32
+/****f* silcutil/silc_atomic_inc32
  *
  * SYNOPSIS
  *
@@ -852,7 +863,7 @@ SILC_ATOMIC_ADD_INT(32, "l");
  *
  ***/
 
-/****f* silcutil/SilcAtomicAPI/silc_atomic_inc16
+/****f* silcutil/silc_atomic_inc16
  *
  * SYNOPSIS
  *
@@ -865,7 +876,7 @@ SILC_ATOMIC_ADD_INT(32, "l");
  *
  ***/
 
-/****f* silcutil/SilcAtomicAPI/silc_atomic_inc8
+/****f* silcutil/silc_atomic_inc8
  *
  * SYNOPSIS
  *
@@ -894,7 +905,7 @@ SILC_ATOMIC_INC_F(bits)                                                     \
 SILC_ATOMIC_INC_F(bits)                                                        \
 {                                                                      \
   /* Windows */                                                                \
-  InterlockedIncrement((LONG)&atomic->value);                          \
+  InterlockedIncrement((LONG *)&atomic->value);                                \
 }
 
 #elif defined(__GNUC__) && (defined(SILC_I486) || defined(SILC_X86_64))
@@ -911,7 +922,7 @@ SILC_ATOMIC_INC_F(bits)                                                     \
 SILC_ATOMIC_INC_F(bits)                                                        \
 {                                                                      \
   /* GCC + IA64 (GCC builtin atomic operations) */                     \
-  __sync_fetch_and_add(&atomic->value, 1);                             \
+  __sync_fetch_and_add((volatile SilcUInt##bits *)&atomic->value, 1);  \
 }
 
 #elif defined(__GNUC__) && defined(SILC_POWERPC)
@@ -941,11 +952,11 @@ SILC_ATOMIC_INC_F(bits)                                                   \
 }
 #endif /* !SILC_THREADS */
 
-SILC_ATOMIC_INC(8, "b");
-SILC_ATOMIC_INC(16, "w");
-SILC_ATOMIC_INC(32, "l");
+SILC_ATOMIC_INC(8, "b")
+SILC_ATOMIC_INC(16, "w")
+SILC_ATOMIC_INC(32, "l")
 
-/****f* silcutil/SilcAtomicAPI/silc_atomic_dec32
+/****f* silcutil/silc_atomic_dec32
  *
  * SYNOPSIS
  *
@@ -958,7 +969,7 @@ SILC_ATOMIC_INC(32, "l");
  *
  ***/
 
-/****f* silcutil/SilcAtomicAPI/silc_atomic_dec16
+/****f* silcutil/silc_atomic_dec16
  *
  * SYNOPSIS
  *
@@ -971,7 +982,7 @@ SILC_ATOMIC_INC(32, "l");
  *
  ***/
 
-/****f* silcutil/SilcAtomicAPI/silc_atomic_dec8
+/****f* silcutil/silc_atomic_dec8
  *
  * SYNOPSIS
  *
@@ -1000,7 +1011,7 @@ SILC_ATOMIC_DEC_F(bits)                                                   \
 SILC_ATOMIC_DEC_F(bits)                                                        \
 {                                                                      \
   /* Windows */                                                                \
-  InterlockedDecrement((LONG)&atomic->value);                          \
+  InterlockedDecrement((LONG *)&atomic->value);                                \
 }
 
 #elif defined(__GNUC__) && (defined(SILC_I486) || defined(SILC_X86_64))
@@ -1017,7 +1028,7 @@ SILC_ATOMIC_DEC_F(bits)                                                   \
 SILC_ATOMIC_DEC_F(bits)                                                        \
 {                                                                      \
   /* GCC + IA64 (GCC builtin atomic operations) */                     \
-  __sync_fetch_and_sub(&atomic->value, 1);                             \
+  __sync_fetch_and_sub((volatile SilcUInt##bits *)&atomic->value, 1);  \
 }
 
 #elif defined(__GNUC__) && defined(SILC_POWERPC)
@@ -1047,11 +1058,11 @@ SILC_ATOMIC_DEC_F(bits)                                                 \
 }
 #endif /* !SILC_THREADS */
 
-SILC_ATOMIC_DEC(8, "b");
-SILC_ATOMIC_DEC(16, "w");
-SILC_ATOMIC_DEC(32, "l");
+SILC_ATOMIC_DEC(8, "b")
+SILC_ATOMIC_DEC(16, "w")
+SILC_ATOMIC_DEC(32, "l")
 
-/****f* silcutil/SilcAtomicAPI/silc_atomic_cas32
+/****f* silcutil/silc_atomic_cas32
  *
  * SYNOPSIS
  *
@@ -1068,7 +1079,7 @@ SILC_ATOMIC_DEC(32, "l");
  *
  ***/
 
-/****f* silcutil/SilcAtomicAPI/silc_atomic_cas16
+/****f* silcutil/silc_atomic_cas16
  *
  * SYNOPSIS
  *
@@ -1085,7 +1096,7 @@ SILC_ATOMIC_DEC(32, "l");
  *
  ***/
 
-/****f* silcutil/SilcAtomicAPI/silc_atomic_cas8
+/****f* silcutil/silc_atomic_cas8
  *
  * SYNOPSIS
  *
@@ -1125,7 +1136,7 @@ SILC_ATOMIC_CAS_F(bits)                                                   \
 {                                                                      \
   /* Windows */                                                                \
   LONG o = old_val, n = new_val;                                       \
-  return InterlockedCompareExchange(&atomic->value, n, o) == o;                \
+  return InterlockedCompareExchange(&atomic->value, n, o) == o;        \
 }
 
 #elif defined(__GNUC__) && (defined(SILC_I486) || defined(SILC_X86_64))
@@ -1136,7 +1147,8 @@ SILC_ATOMIC_CAS_F(bits)                                                   \
   SilcUInt##bits ret;                                                  \
   __asm __volatile(SILC_SMP_LOCK "cmpxchg" bp " %2, %1"                        \
                   : "=a" (ret), "=m" (atomic->value)                   \
-                  : "r" (new_val), "m" (atomic->value), "0" (old_val)); \
+                  : "r" (new_val), "m" (atomic->value),                \
+                  "0" (old_val));                                      \
   return ret == (SilcUInt##bits)old_val;                               \
 }
 
@@ -1146,7 +1158,8 @@ SILC_ATOMIC_CAS_F(bits)                                                   \
 {                                                                      \
   /* GCC + IA64 (GCC builtin atomic operations) */                     \
   SilcUInt32 o = old_val, n = new_val;                                 \
-  return __sync_bool_compare_and_swap(&atomic->value, o, n);           \
+  return __sync_bool_compare_and_swap((volatile SilcUInt32 *)&atomic->value, \
+                                     o, n);                            \
 }
 
 #elif defined(__GNUC__) && defined(SILC_POWERPC)
@@ -1173,11 +1186,11 @@ SILC_ATOMIC_CAS_F(bits)                                                 \
 }
 #endif /* !SILC_THREADS */
 
-SILC_ATOMIC_CAS(8, "b");
-SILC_ATOMIC_CAS(16, "w");
-SILC_ATOMIC_CAS(32, "l");
+SILC_ATOMIC_CAS(8, "b")
+SILC_ATOMIC_CAS(16, "w")
+SILC_ATOMIC_CAS(32, "l")
 
-/****f* silcutil/SilcAtomicAPI/silc_atomic_cas_pointer
+/****f* silcutil/silc_atomic_cas_pointer
  *
  * SYNOPSIS
  *
@@ -1208,7 +1221,8 @@ SilcBool silc_atomic_cas_pointer(SilcAtomicPointer *atomic, void *old_val,
 
 #elif defined(SILC_WIN32)
   /* Windows */
-  return InterlockedCompareExchangePointer(&atomic->value, n, o) == o;
+  return InterlockedCompareExchangePointer(&atomic->value, new_val, old_val)
+    == old_val;
 
 #elif defined(__GNUC__) && defined(SILC_I486)
   /* GCC + i486 */
@@ -1228,7 +1242,7 @@ SilcBool silc_atomic_cas_pointer(SilcAtomicPointer *atomic, void *old_val,
 
 #elif defined(__GNUC__) && defined(SILC_IA64)
   /* GCC + IA64 (GCC builtin atomic operations) */
-  return  __sync_bool_compare_and_swap((long)&atomic->value, (long)old_val,
+  return  __sync_bool_compare_and_swap((long *)&atomic->value, (long)old_val,
                                       (long)new_val);
 
 #elif defined(__GNUC__) && defined(SILC_POWERPC)