Now with patch!

On 3 June 2011 00:36, Nick Lewycky <[email protected]> wrote:

> The attached patch implements the ARM EABI versions of
> __cxa_guard_{acquire,release,abort} while trying to share as much code as
> possible. It appears to me that it's unlikely that this will build correctly
> on __APPLE__ machines, but that's beyond my ability to deal with here. I
> have also not actually tested this on an ARM machine, but I did #define
> LIBCXXABI_ARMEABI and build the tests and those pass on x86-64.
>
> Once again, please review!
>
> Nick
>
>
Index: include/cxxabi.h
===================================================================
--- include/cxxabi.h	(revision 132528)
+++ include/cxxabi.h	(working copy)
@@ -61,9 +61,15 @@
 extern LIBCXXABI_NORETURN void __cxa_deleted_virtual(void);
 
 // 3.3.2 One-time Construction API
+#ifdef LIBCXXABI_ARMEABI
+extern int  __cxa_guard_acquire(uint32_t*);
+extern void __cxa_guard_release(uint32_t*);
+extern void __cxa_guard_abort(uint32_t*);
+#else
 extern int  __cxa_guard_acquire(uint64_t*);
 extern void __cxa_guard_release(uint64_t*);
 extern void __cxa_guard_abort(uint64_t*);
+#endif
 
 // 3.3.3 Array Construction and Destruction API
 extern void* __cxa_vec_new(size_t element_count, 
Index: src/cxa_guard.cpp
===================================================================
--- src/cxa_guard.cpp	(revision 132528)
+++ src/cxa_guard.cpp	(working copy)
@@ -20,6 +20,38 @@
 namespace
 {
 
+#if LIBCXX_ARMEABI
+
+// A 32-bit, 4-byte-aligned static data value. The least significant 2 bits must
+// be statically initialized to 0.
+typedef uint32_t guard_type;
+
+// Test the lowest bit.
+inline bool is_initialized(guard_type* guard_object) {
+    return (*guard_object) & 1;
+}
+
+inline void set_initialized(guard_type* guard_object) {
+    *guard_object |= 1;
+}
+
+#else
+
+typedef uint64_t guard_type;
+
+bool is_initialized(guard_type* guard_object) {
+    char* initialized = (char*)guard_object;
+    return *initialized;
+}
+
+void set_initialized(guard_type* guard_object) {
+    char* initialized = (char*)guard_object;
+    *initialized = 1;
+}
+
+#endif
+
+
 void abort_message(const char* s)
 {
     fputs(s, stderr);
@@ -96,6 +128,31 @@
     x = f.guard;
 }
 
+inline
+lock_type
+get_lock(uint32_t x)
+{
+    union
+    {
+        uint32_t guard;
+        uint8_t lock[2];
+    } f = {x};
+    return f.lock[1] != 0;
+}
+
+inline
+void
+set_lock(uint32_t& x, lock_type y)
+{
+    union
+    {
+        uint32_t guard;
+        uint8_t lock[2];
+    } f = {0};
+    f.lock[1] = y;
+    x = f.guard;
+}
+
 #endif  // __APPLE__
 
 }  // unnamed namespace
@@ -103,7 +160,7 @@
 extern "C"
 {
 
-int __cxa_guard_acquire(uint64_t* guard_object)
+int __cxa_guard_acquire(guard_type* guard_object)
 {
     char* initialized = (char*)guard_object;
     if (pthread_mutex_lock(&guard_mut))
@@ -125,7 +182,7 @@
                     abort_message("__cxa_guard_acquire condition variable wait failed");
                 lock = get_lock(*guard_object);
             } while (lock);
-            result = *initialized == 0;
+            result = !is_initialized();
             if (result)
                 set_lock(*guard_object, id);
         }
@@ -145,20 +202,19 @@
     return result;
 }
 
-void __cxa_guard_release(uint64_t* guard_object)
+void __cxa_guard_release(guard_type* guard_object)
 {
-    char* initialized = (char*)guard_object;
     if (pthread_mutex_lock(&guard_mut))
         abort_message("__cxa_guard_release failed to acquire mutex");
     *guard_object = 0;
-    *initialized = 1;
+    set_initialized(guard_object);
     if (pthread_mutex_unlock(&guard_mut))
         abort_message("__cxa_guard_release failed to release mutex");
     if (pthread_cond_broadcast(&guard_cv))
         abort_message("__cxa_guard_release failed to broadcast condition variable");
 }
 
-void __cxa_guard_abort(uint64_t* guard_object)
+void __cxa_guard_abort(guard_type* guard_object)
 {
     if (pthread_mutex_lock(&guard_mut))
         abort_message("__cxa_guard_abort failed to acquire mutex");
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to