This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Testing parallel mode and PR34106


Should I be able to run "make check-parallel" with no FAILs?  Even
before I touched any parallel headers I'm seeing several failures.

This isn't strictly necessary, but might be a good idea:

Index: include/parallel/tree.h
===================================================================
--- include/parallel/tree.h     (revision 130747)
+++ include/parallel/tree.h     (working copy)
@@ -1090,7 +1090,7 @@
        * them have finished).
        * \li READY_NOT: at least one of the children
        * concatenation_problem have not finished */
-      int is_ready;
+      _Atomic_word is_ready;

       /** @brief Parent concatenation problem to solve when @c
          is_ready = READY_YES */


Should include/parallel/types.h use BITS_PER_UNIT here, not 8?
  /**
   * @brief Number of bits of ::lcas_t.
   */
  static const int lcas_t_bits = sizeof(lcas_t) * 8;

For parallel/compatibility.h, fetch_and_add can't be easily
implemented with __exchange_and_add_dispatch because it needs to work
with 32 and 64 bit types, and the ext/atomicity.h dispatchers only
support _Atomic_word, so the best I've come up with is:

  template<typename T>
  inline T
  fetch_and_add(volatile T* ptr, T addend)
  {
#if _GLIBCXX_ATOMIC_BUILTINS
    return __sync_fetch_and_add(ptr, addend);
#else
#pragma message("slow fetch_and_add")
#pragma omp critical
    {
      T tmp = *ptr;
      *ptr += addend;
      return tmp;
    }
#endif
  }

compare_and_swap could check __default_lock_policy == _S_atomic but
that only guarantees 16-bit and 32-bit types can be used.  In the
absence of a more fine-grained set of enumerations for _Lock_policy
(which would complicate shared_ptr slightly) this seems to work:

  template<size_t _Sz> struct _CAS_helper { };

  template<typename T, size_t _Sz>
  bool
  __compare_and_swap_helper(volatile T* ptr, T comparand, T replacement,
                            _CAS_helper<_Sz>)
  {
#pragma message("slow compare_and_swap")
    bool res = false;
#pragma omp critical
    {
      if (*ptr == comparand)
	{
	  *ptr = replacement;
	  res = true;
	}
    }
    return res;
  }

#if __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1
  template<typename T>
  inline bool
  __compare_and_swap_helper(volatile T* ptr, T comparand, T replacement,
                            _CAS_helper<1>)
  {
    return __sync_bool_compare_and_swap(ptr, comparand, replacement);
  }
#endif

// repeat for _2 _4 _8 _16 ...

  template<typename T>
  inline bool
  compare_and_swap(volatile T* ptr, T comparand, T replacement)
  {
    return __compare_and_swap_helper(ptr, comparand, replacement,
                                     _CAS_helper<sizeof(T)>());
  }

I think this is going in the opposite direction to what Benjamin
wanted, where _Lock_policy dictates this sort of thing.  I don't yet
see how to make that work without making _Lock_policy far more
fine-grained, in which case it becomes less useful for other cases.

Jon


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]