Author: jesus
Date: Sat Nov 13 15:58:58 2010
New Revision: 1034786
URL: http://svn.apache.org/viewvc?rev=1034786&view=rev
Log:
TS-533 and TS-135
This is a sad day of defeat. Not my defeat, but more a collective human defeat.
Question: "Chips fabricated today don't have 64bit atomic primitives?"
Answer: "Be sad."
The ARM box we're working on (armv5tejl) doesn't support any 64bit primitives.
This means we need a method of using a global (yes, giant lock of death) to
protect modifications of arbitrary 64bit integers in process space. We could
make this less contentious by allocating pagesize/8 mutexs and then protecting
an int64 based on its page offset. Instead, I think we should mobilize to
burn these architectures to the ground and use public embarrassment to fix
future instruction sets.
If another platform has this issue, we'll want to change the define to:
TS_ARCHITECTURE_LACKS_64BIT_INSTRUCTIONS and turn on the global death lock
based on that.
This does not change performance on any other platform -- it's compile time
capital punishment.
Modified:
trafficserver/traffic/trunk/libinktomi++/ink_atomic.h
trafficserver/traffic/trunk/libinktomi++/ink_mutex.cc
Modified: trafficserver/traffic/trunk/libinktomi++/ink_atomic.h
URL:
http://svn.apache.org/viewvc/trafficserver/traffic/trunk/libinktomi%2B%2B/ink_atomic.h?rev=1034786&r1=1034785&r2=1034786&view=diff
==============================================================================
--- trafficserver/traffic/trunk/libinktomi++/ink_atomic.h (original)
+++ trafficserver/traffic/trunk/libinktomi++/ink_atomic.h Sat Nov 13 15:58:58
2010
@@ -44,6 +44,7 @@
#include "ink_port.h"
#include "ink_apidefs.h"
+#include "ink_mutex.h"
typedef volatile int32 vint32;
typedef volatile int64 vint64;
@@ -88,14 +89,44 @@ static inline void *ink_atomic_increment
/* see http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html */
static inline int32 ink_atomic_swap(pvint32 mem, int32 value) { return
__sync_lock_test_and_set(mem, value); }
-static inline int64 ink_atomic_swap64(pvint64 mem, int64 value) { return
__sync_lock_test_and_set(mem, value); }
static inline void *ink_atomic_swap_ptr(vvoidp mem, void *value) { return
__sync_lock_test_and_set((void**)mem, value); }
static inline int ink_atomic_cas(pvint32 mem, int old, int new_value) { return
__sync_bool_compare_and_swap(mem, old, new_value); }
-static inline int64 ink_atomic_cas64(pvint64 mem, int64 old, int64 new_value)
{ return __sync_bool_compare_and_swap(mem, old, new_value); }
static inline int ink_atomic_cas_ptr(pvvoidp mem, void* old, void* new_value)
{ return __sync_bool_compare_and_swap(mem, old, new_value); }
static inline int ink_atomic_increment(pvint32 mem, int value) { return
__sync_fetch_and_add(mem, value); }
-static inline int64 ink_atomic_increment64(pvint64 mem, int64 value) { return
__sync_fetch_and_add(mem, value); }
static inline void *ink_atomic_increment_ptr(pvvoidp mem, intptr_t value) {
return __sync_fetch_and_add((void**)mem, value); }
+#if defined(__arm__) && (SIZEOF_VOIDP == 4)
+extern ProcessMutex __global_death;
+
+static inline int64 ink_atomic_swap64(pvint64 mem, int64 value) {
+ int64 old;
+ ink_mutex_acquire(&__global_death);
+ old = *mem;
+ *mem = value;
+ ink_mutex_release(&__global_death);
+ return old;
+}
+static inline int64 ink_atomic_cas64(pvint64 mem, int64 old, int64 new_value) {
+ int64 curr;
+ ink_mutex_acquire(&__global_death);
+ curr = *mem;
+ if(old == curr) *mem = new_value;
+ ink_mutex_release(&__global_death);
+ if(old == curr) return 1;
+ return 0;
+}
+static inline int64 ink_atomic_increment64(pvint64 mem, int64 value) {
+ int64 curr;
+ ink_mutex_acquire(&__global_death);
+ curr = *mem;
+ *mem = curr + value;
+ ink_mutex_release(&__global_death);
+ return curr + value;
+}
+#else
+static inline int64 ink_atomic_swap64(pvint64 mem, int64 value) { return
__sync_lock_test_and_set(mem, value); }
+static inline int64 ink_atomic_cas64(pvint64 mem, int64 old, int64 new_value)
{ return __sync_bool_compare_and_swap(mem, old, new_value); }
+static inline int64 ink_atomic_increment64(pvint64 mem, int64 value) { return
__sync_fetch_and_add(mem, value); }
+#endif
/* not used for Intel Processors which have sequential(esque) consistency */
#define INK_WRITE_MEMORY_BARRIER
Modified: trafficserver/traffic/trunk/libinktomi++/ink_mutex.cc
URL:
http://svn.apache.org/viewvc/trafficserver/traffic/trunk/libinktomi%2B%2B/ink_mutex.cc?rev=1034786&r1=1034785&r2=1034786&view=diff
==============================================================================
--- trafficserver/traffic/trunk/libinktomi++/ink_mutex.cc (original)
+++ trafficserver/traffic/trunk/libinktomi++/ink_mutex.cc Sat Nov 13 15:58:58
2010
@@ -29,6 +29,9 @@
x_pthread_mutexattr_t _g_mattr;
+ProcessMutex __global_death = PTHREAD_MUTEX_INITIALIZER;
+ProcessMutex *gobal_death_mutex = &__global_death;
+
void
ink_ProcessMutex_init(ProcessMutex * m, const char *name)
{
@@ -71,5 +74,8 @@ ink_ProcessMutex_print(FILE * out, Proce
{
(void) out;
(void) m;
- fprintf(out, "ProcessMutex\n");
+ if(m == gobal_death_mutex)
+ fprintf(out, "Global ProcessMutex\n");
+ else
+ fprintf(out, "ProcessMutex\n");
}