diff options
author | Balaji V. Iyer <balaji.v.iyer@intel.com> | 2012-12-28 23:50:07 +0000 |
---|---|---|
committer | Balaji V. Iyer <balaji.v.iyer@intel.com> | 2012-12-28 23:50:07 +0000 |
commit | e3e551a667a641fadf4a67dabe48deb78d91c446 (patch) | |
tree | 303275ad3fd846a48b82e00ab210ebdbd82ccecd | |
parent | 20a71961b2e317cce94b64311a5dcc46b6f376b1 (diff) |
Update-back libcilkrts to 2856.
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/cilkplus@194746 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | libcilkrts/ChangeLog.cilkplus | 20 | ||||
-rw-r--r-- | libcilkrts/include/cilk/cilk_api.h | 20 | ||||
-rw-r--r-- | libcilkrts/include/cilk/common.h | 3 | ||||
-rw-r--r-- | libcilkrts/include/cilk/reducer.h | 16 | ||||
-rw-r--r-- | libcilkrts/include/cilk/reducer_list.h | 30 | ||||
-rw-r--r-- | libcilkrts/include/cilk/reducer_max.h | 20 | ||||
-rw-r--r-- | libcilkrts/include/cilk/reducer_min.h | 22 | ||||
-rw-r--r-- | libcilkrts/include/cilk/reducer_opadd.h | 36 | ||||
-rw-r--r-- | libcilkrts/include/cilk/reducer_opand.h | 22 | ||||
-rw-r--r-- | libcilkrts/include/cilk/reducer_opor.h | 21 | ||||
-rw-r--r-- | libcilkrts/include/cilk/reducer_opxor.h | 11 | ||||
-rw-r--r-- | libcilkrts/include/cilk/reducer_ostream.h | 8 | ||||
-rw-r--r-- | libcilkrts/include/cilk/reducer_string.h | 21 | ||||
-rw-r--r-- | libcilkrts/include/internal/cilk_version.h | 13 | ||||
-rw-r--r-- | libcilkrts/include/internal/rev.mk | 4 | ||||
-rw-r--r-- | libcilkrts/runtime/cilk-abi-cilk-for.cpp | 146 | ||||
-rw-r--r-- | libcilkrts/runtime/except-gcc.cpp | 7 | ||||
-rw-r--r-- | libcilkrts/runtime/global_state.cpp | 31 | ||||
-rw-r--r-- | libcilkrts/runtime/os-unix.c | 14 | ||||
-rw-r--r-- | libcilkrts/runtime/sysdep-unix.c | 12 |
20 files changed, 336 insertions, 141 deletions
diff --git a/libcilkrts/ChangeLog.cilkplus b/libcilkrts/ChangeLog.cilkplus index 62c8f91580b..0903be511b6 100644 --- a/libcilkrts/ChangeLog.cilkplus +++ b/libcilkrts/ChangeLog.cilkplus @@ -1,3 +1,23 @@ +2012-12-06 Balaji V. Iyer <balaji.v.iyer@intel.com> + + * include/cilk/reduce_min.h: Updated to revision 2856. + * include/cilk/reduce_max.h: Likewise. + * include/cilk/reducer_opadd.h: Likewise. + * include/cilk/reducer_opand.h: Likewise. + * include/cilk/cilk_api.h: Likewise. + * include/cilk/reducer_string.h: Likewise. + * include/cilk/reducer_opxor.h: Likewise. + * include/cilk/reduce_ostream.h: Likewise. + * include/cilk/reducer_list.h: Likewise. + * include/cilk/reducer_opor.h: Likewise. + * include/cilk/common.h: Likewise. + * include/internal/rev.mk: Likewise. + * runtime/os-unix.c: Likewise. + * runtime/cilk-abi-cilk-for.cpp: Likewise. + * runtime/except-gcc.cpp: Likewise. + * runtime/global_state.cpp: Likewise. + * runtime/sysdep-unix.c: Likewise. + 2012-06-12 Balaji V. Iyer <balaji.v.iyer@intel.com> * configure: Updated to revision 2546. diff --git a/libcilkrts/include/cilk/cilk_api.h b/libcilkrts/include/cilk/cilk_api.h index 29eff035cf1..f7078ec2373 100644 --- a/libcilkrts/include/cilk/cilk_api.h +++ b/libcilkrts/include/cilk/cilk_api.h @@ -50,7 +50,15 @@ #ifndef INCLUDED_CILK_API_H #define INCLUDED_CILK_API_H -#ifndef CILK_STUB +#ifndef CILK_STUB /* Real (non-stub) definitions below */ + +#if ! defined(__cilk) && ! defined(USE_CILK_API) +# ifdef _WIN32 +# pragma message("Warning: Cilk ABI is being used with non-Cilk compiler (or Cilk is disabled)") +# else +# warning Cilk ABI is being used with non-Cilk compiler (or Cilk is disabled) +# endif +#endif #include <cilk/common.h> @@ -194,10 +202,10 @@ typedef void (*__cilkrts_pfn_seh_callback)(const _EXCEPTION_RECORD *exception); * runtime aborts the application. */ CILK_API(int) __cilkrts_set_seh_callback(__cilkrts_pfn_seh_callback pfn); -#endif +#endif /* _WIN32 */ #if __CILKRTS_ABI_VERSION >= 1 -// Pedigree API is available only for compilers that use ABI version >= 1. +/* Pedigree API is available only for compilers that use ABI version >= 1. */ /** * Pedigree API @@ -337,7 +345,7 @@ int __cilkrts_bump_loop_rank(void) return __cilkrts_bump_loop_rank_internal(__cilkrts_get_tls_worker()); } -#endif // __CILKRTS_ABI_VERSION >= 1 +#endif /* __CILKRTS_ABI_VERSION >= 1 */ __CILKRTS_END_EXTERN_C @@ -377,10 +385,10 @@ __cilkrts_pedigree __cilkrts_get_pedigree_stub(void) return ans; } -// Renamed to an actual stub method. +/* Renamed to an actual stub method. */ #define __cilkrts_get_pedigree() __cilkrts_get_pedigree_stub() -#endif // __CILKRTS_ABI_VERSION >= 1 +#endif /* __CILKRTS_ABI_VERSION >= 1 */ #endif /* CILK_STUB */ diff --git a/libcilkrts/include/cilk/common.h b/libcilkrts/include/cilk/common.h index 419641180a0..bc28100bfcb 100644 --- a/libcilkrts/include/cilk/common.h +++ b/libcilkrts/include/cilk/common.h @@ -53,6 +53,9 @@ # define CILK_EXPORT __declspec(dllimport) # define CILK_EXPORT_DATA __declspec(dllimport) # endif /* IN_CILK_RUNTIME */ +#elif defined(__CYGWIN__) +# define CILK_EXPORT /* nothing */ +# define CILK_EXPORT_DATA /* nothing */ #else /* Unix/gcc */ # ifdef IN_CILK_RUNTIME # define CILK_EXPORT __attribute__((visibility("protected"))) diff --git a/libcilkrts/include/cilk/reducer.h b/libcilkrts/include/cilk/reducer.h index 9f23d8aece3..d44823ccea3 100644 --- a/libcilkrts/include/cilk/reducer.h +++ b/libcilkrts/include/cilk/reducer.h @@ -107,9 +107,10 @@ namespace cilk { /// reducer CLASS TEMPLATE /// -/// A reducer is instantiated on a Monoid. The Monoid provides the value type, -/// associative reduce function, and identity for the reducer. Function view() -/// and operator()() return the current view of the reducer. +/// A reducer is instantiated on a Monoid. The Monoid provides the value +/// type, associative reduce function, and identity for the reducer. Function +/// view(), operator*(), and operator()() return the current view of the +/// reducer, although operator()() is deprecated. template <class Monoid> class reducer { @@ -278,6 +279,15 @@ class reducer return const_cast<reducer*>(this)->view(); } + /// "Dereference" reducer to return the current view. + value_type& operator*() { return view(); } + value_type const& operator*() const { return view(); } + + /// "Dereference" reducer to return the current view. + value_type* operator->() { return &view(); } + value_type const* operator->() const { return &view(); } + + /// operator()() is deprecated. Use operator*() instead. value_type& operator()() { return view(); } value_type const& operator()() const { return view(); } diff --git a/libcilkrts/include/cilk/reducer_list.h b/libcilkrts/include/cilk/reducer_list.h index a2fd36a78ef..d021577f816 100644 --- a/libcilkrts/include/cilk/reducer_list.h +++ b/libcilkrts/include/cilk/reducer_list.h @@ -60,7 +60,8 @@ * } * * std::cout << "The result is: "; - * for (std::list<int>::iterator i = result.begin(); i != result.end(); ++i) + * for (std::list<int>::iterator i = result.begin(); i != result.end(); + * ++i) * { * std::cout << *i << " " << std::endl; * } @@ -70,7 +71,8 @@ *.. * Changing the 'for' to a 'cilk_for' will cause the loop to run in parallel, * but doing so will create a data race on the 'result' list. - * The race is solved by changing 'result' to a 'reducer_list_append' hyperobject: + * The race is solved by changing 'result' to a 'reducer_list_append' + * hyperobject: *.. * int compute(const X& v); * @@ -80,15 +82,15 @@ * extern X myArray[ARRAY_SIZE]; * // ... * - * cilk::hyperobject<cilk::reducer_list_append<int> > result; + * cilk::reducer_list_append<int> result; * cilk_for (std::size_t i = 0; i < ARRAY_SIZE; ++i) * { - * result.push_back(compute(myArray[i])); + * result->push_back(compute(myArray[i])); * } * * std::cout << "The result is: "; - * const std::list &r = result.get_value(); - * for (std::list<int>::iterator i = r.begin(); i != r.end(); ++i) + * const std::list &r = result->get_value(); + * for (std::list<int>::const_iterator i = r.begin(); i != r.end(); ++i) * { * std::cout << *i << " " << std::endl; * } @@ -104,7 +106,7 @@ * ordered list of items. Lists accumulated in Cilk++ strands will be merged * to maintain the order of the lists - the order will be the same as if the * application was run on a single core. - *.. + * * The the current value of the reducer can be gotten and set using the * 'get_value', 'get_reference', and 'set_value' methods. As with most * reducers, these methods produce deterministic results only if called before @@ -122,8 +124,8 @@ namespace cilk { /** - * @brief Reducer hyperobject to accumulate a list of elements where elements are - * added to the end of the list. + * @brief Reducer hyperobject to accumulate a list of elements where elements + * are added to the end of the list. */ template<class _Ty, class _Ax = std::allocator<_Ty> > @@ -169,6 +171,11 @@ public: // Add an element to the end of the list void push_back(const _Ty element); + reducer_list_append& operator*() { return *this; } + reducer_list_append const& operator*() const { return *this; } + + reducer_list_append* operator->() { return this; } + reducer_list_append const* operator->() const { return this; } private: // Not copyable @@ -365,6 +372,11 @@ public: // Add an element to the beginning of the list void push_front(const _Ty element); + reducer_list_prepend& operator*() { return *this; } + reducer_list_prepend const& operator*() const { return *this; } + + reducer_list_prepend* operator->() { return this; } + reducer_list_prepend const* operator->() const { return this; } private: // Not copyable diff --git a/libcilkrts/include/cilk/reducer_max.h b/libcilkrts/include/cilk/reducer_max.h index c545c401ef9..0b1c2960d63 100644 --- a/libcilkrts/include/cilk/reducer_max.h +++ b/libcilkrts/include/cilk/reducer_max.h @@ -74,9 +74,9 @@ * * cilk_for (int i = 0; i < ARRAY_SIZE; ++i) * { - * max.calc_max(a[i]); + * max->calc_max(a[i]); * } - * std::cout << "max = " << max.get_value() << std::endl; + * std::cout << "max = " << max->get_value() << std::endl; * * ... * } @@ -94,8 +94,8 @@ * { * rmi.calc_max(i, a[i]); * } - * std::cout << "max = " << rmi.get_value() << - * ", index = " << rmi.get_index() << std::endl; + * std::cout << "max = " << rmi->get_value() << + * ", index = " << rmi->get_index() << std::endl; * * ... * } @@ -304,6 +304,12 @@ public: /// operation must involve this hyperobject, i.e., x = max_of(x, 5); reducer_max& operator=(const temp_max &temp); + reducer_max& operator*() { return *this; } + reducer_max const& operator*() const { return *this; } + + reducer_max* operator->() { return this; } + reducer_max const* operator->() const { return this; } + private: // Not copyable reducer_max(const reducer_max&); @@ -631,6 +637,12 @@ public: // DEPRECATED. Use calc_max instead. void max_of(const Index& index, const Value& value) {calc_max(index,value);} + reducer_max_index& operator*() { return *this; } + reducer_max_index const& operator*() const { return *this; } + + reducer_max_index* operator->() { return this; } + reducer_max_index const* operator->() const { return this; } + private: // Not copyable reducer_max_index(const reducer_max_index&); diff --git a/libcilkrts/include/cilk/reducer_min.h b/libcilkrts/include/cilk/reducer_min.h index 5a515e9f73f..22694b101d3 100644 --- a/libcilkrts/include/cilk/reducer_min.h +++ b/libcilkrts/include/cilk/reducer_min.h @@ -74,9 +74,9 @@ * * cilk_for (int i = 0; i < ARRAY_SIZE; ++i) * { - * min.calc_min(a[i]); + * min->calc_min(a[i]); * } - * std::cout << "min = " << min.get_value() << std::endl; + * std::cout << "min = " << min->get_value() << std::endl; * * ... * } @@ -92,10 +92,10 @@ * * cilk_for (int i = 0; i < ARRAY_SIZE; ++i) * { - * rmi.calc_min(i, a[i]); + * rmi->calc_min(i, a[i]); * } - * std::cout << "min = " << rmi.get_value() << - * ", index = " << rmi.get_index() << std::endl; + * std::cout << "min = " << rmi->get_value() << + * ", index = " << rmi->get_index() << std::endl; * * ... * } @@ -303,6 +303,12 @@ public: /// operation must involve this hyperobject, i.e., x = min_of(x, 5); reducer_min& operator=(const temp_min &temp); + reducer_min& operator*() { return *this; } + reducer_min const& operator*() const { return *this; } + + reducer_min* operator->() { return this; } + reducer_min const* operator->() const { return this; } + private: // Not copyable reducer_min(const reducer_min&); @@ -631,6 +637,12 @@ public: void min_of(const Index& index, const Value& value) { calc_min(index,value); } + reducer_min_index& operator*() { return *this; } + reducer_min_index const& operator*() const { return *this; } + + reducer_min_index* operator->() { return this; } + reducer_min_index const* operator->() const { return this; } + private: // Not copyable reducer_min_index(const reducer_min_index&); diff --git a/libcilkrts/include/cilk/reducer_opadd.h b/libcilkrts/include/cilk/reducer_opadd.h index 85dc51642e4..9380a0ac122 100644 --- a/libcilkrts/include/cilk/reducer_opadd.h +++ b/libcilkrts/include/cilk/reducer_opadd.h @@ -65,7 +65,7 @@ * extern X myArray[ARRAY_SIZE]; * // ... * - * int result; + * int result = 0; * for (std::size_t i = 0; i < ARRAY_SIZE; ++i) * { * result += compute(myArray[i]); @@ -91,7 +91,7 @@ * cilk::reducer_opadd<int> result; * cilk_for (std::size_t i = 0; i < ARRAY_SIZE; ++i) * { - * result += compute(myArray[i]); + * *result += compute(myArray[i]); * } * * std::cout << "The result is: " << result.get_value() << std::endl; @@ -105,22 +105,22 @@ * Given 'reducer_opadd' objects, x and y, the following are * valid statements: *.. - * x += 5; - * x = x + 5; - * x -= 5; - * y = y - 5; - * ++x; - * --x; - * x++; - * x--; + * *x += 5; + * *x = *x + 5; + * *x -= 5; + * *y = *y - 5; + * ++*x; + * --*x; + * (*x)++; + * (*x)--; *.. * The following are not valid expressions and will result in a run-time error * in a debug build: *.. - * x = y; // Cannot assign one reducer to another - * x = y + 5; // Mixed reducers - * x = 5 + x; // operator+ is not necessarily commutative - * x = 5 - x; // Violates associativity + * x = y; // Cannot assign one reducer to another + * *x = *y + 5; // Mixed reducers + * *x = 5 + *x; // operator+ is not necessarily commutative + * *x = 5 - *x; // Violates associativity *.. * The the current value of the reducer can be get and set using the * 'get_value' and 'set_value' methods, respectively. As with most reducers, @@ -134,7 +134,7 @@ * cilk::reducer_opadd<int> x; * cilk_spawn func(); * int a = x.get_value(); - * x += 5; + * *x += 5; * int b = x.get_value(); * assert(b - a == 5); *.. @@ -253,6 +253,12 @@ public: /// must involve this reducer, i.e., x = x + 5; not x = y + 5; reducer_opadd& operator=(const temp_sum& temp); + reducer_opadd& operator*() { return *this; } + reducer_opadd const& operator*() const { return *this; } + + reducer_opadd* operator->() { return this; } + reducer_opadd const* operator->() const { return this; } + private: friend class temp_sum; diff --git a/libcilkrts/include/cilk/reducer_opand.h b/libcilkrts/include/cilk/reducer_opand.h index 63f34d05ac6..0ee7b9faf57 100644 --- a/libcilkrts/include/cilk/reducer_opand.h +++ b/libcilkrts/include/cilk/reducer_opand.h @@ -73,7 +73,7 @@ * extern X myArray[ARRAY_SIZE]; * // ... * - * unsigned int result; + * unsigned int result = 1; * for (std::size_t i = 0; i < ARRAY_SIZE; ++i) * { * result &= compute(myArray[i]); @@ -97,10 +97,10 @@ * extern X myArray[ARRAY_SIZE]; * // ... * - * cilk::reducer_opand<unsigned int> result; + * cilk::reducer_opand<unsigned int> result(1); * cilk_for (std::size_t i = 0; i < ARRAY_SIZE; ++i) * { - * result &= compute(myArray[i]); + * *result &= compute(myArray[i]); * } * * std::cout << "The result is: " @@ -115,15 +115,15 @@ * Given 'reducer_opand' objects, x and y, the following are * valid statements: *.. - * x &= 5; - * x = x & 5; + * *x &= 5; + * *x = *x & 5; *.. * The following are not valid expressions and will result in a run-time error * in a debug build: *.. - * x = y; // Cannot assign one reducer to another - * x = y & 5; // Mixed reducers - * x = 5 & x; // operator& is not necessarily commutative + * x = y; // Cannot assign one reducer to another + * *x = *y & 5; // Mixed reducers + * *x = 5 & *x; // operator& is not necessarily commutative *.. *.. * @@ -219,6 +219,12 @@ class reducer_opand /// must involve this reducer, i.e., x = x + 5; not x = y + 5; reducer_opand& operator=(const temp_and& temp); + reducer_opand& operator*() { return *this; } + reducer_opand const& operator*() const { return *this; } + + reducer_opand* operator->() { return this; } + reducer_opand const* operator->() const { return this; } + private: friend class temp_and; diff --git a/libcilkrts/include/cilk/reducer_opor.h b/libcilkrts/include/cilk/reducer_opor.h index e53ea1be27d..2b2de9bc163 100644 --- a/libcilkrts/include/cilk/reducer_opor.h +++ b/libcilkrts/include/cilk/reducer_opor.h @@ -73,7 +73,7 @@ * extern X myArray[ARRAY_SIZE]; * // ... * - * unsigned int result; + * unsigned int result = 0; * for (std::size_t i = 0; i < ARRAY_SIZE; ++i) * { * result |= compute(myArray[i]); @@ -100,7 +100,7 @@ * cilk::reducer_opor<unsigned int> result; * cilk_for (std::size_t i = 0; i < ARRAY_SIZE; ++i) * { - * result |= compute(myArray[i]); + * *result |= compute(myArray[i]); * } * * std::cout << "The result is: " @@ -115,16 +115,15 @@ * Given 'reducer_opor' objects, x and y, the following are * valid statements: *.. - * x |= 5; - * x = x | 5; + * *x |= 5; + * *x = *x | 5; *.. * The following are not valid expressions and will result in a run-time error * in a debug build: *.. - * x = y; // Cannot assign one reducer to another - * x = y | 5; // Mixed reducers - * x = 5 | x; // operator| is not necessarily commutative - *.. + * x = y; // Cannot assign one reducer to another + * *x = *y | 5; // Mixed reducers + * *x = 5 | *x; // operator| is not necessarily commutative *.. * * Requirements on the 'Type' parameter @@ -215,6 +214,12 @@ class reducer_opor /// must involve this reducer, i.e., x = x + 5; not x = y + 5; reducer_opor& operator=(const temp_or& temp); + reducer_opor& operator*() { return *this; } + reducer_opor const& operator*() const { return *this; } + + reducer_opor* operator->() { return this; } + reducer_opor const* operator->() const { return this; } + private: friend class temp_or; diff --git a/libcilkrts/include/cilk/reducer_opxor.h b/libcilkrts/include/cilk/reducer_opxor.h index 7441a67db9b..8aad7c052fa 100644 --- a/libcilkrts/include/cilk/reducer_opxor.h +++ b/libcilkrts/include/cilk/reducer_opxor.h @@ -73,7 +73,7 @@ * extern X myArray[ARRAY_SIZE]; * // ... * - * unsigned int result; + * unsigned int result = 0; * for (std::size_t i = 0; i < ARRAY_SIZE; ++i) * { * result ^= compute(myArray[i]); @@ -100,7 +100,7 @@ * cilk::reducer_opxor<unsigned int> result; * cilk_for (std::size_t i = 0; i < ARRAY_SIZE; ++i) * { - * result ^= compute(myArray[i]); + * *result ^= compute(myArray[i]); * } * * std::cout << "The result is: " @@ -125,7 +125,6 @@ * x = y ^ 5; // Mixed reducers * x = 5 ^ x; // operator^ is not necessarily commutative *.. - *.. * * Requirements on the 'Type' parameter * ==================================== @@ -214,6 +213,12 @@ class reducer_opxor /// must involve this reducer, i.e., x = x + 5; not x = y + 5; reducer_opxor& operator=(const temp_xor& temp); + reducer_opxor& operator*() { return *this; } + reducer_opxor const& operator*() const { return *this; } + + reducer_opxor* operator->() { return this; } + reducer_opxor const* operator->() const { return this; } + private: friend class temp_or; diff --git a/libcilkrts/include/cilk/reducer_ostream.h b/libcilkrts/include/cilk/reducer_ostream.h index f95278df3cd..9d57824bce4 100644 --- a/libcilkrts/include/cilk/reducer_ostream.h +++ b/libcilkrts/include/cilk/reducer_ostream.h @@ -77,7 +77,7 @@ * void compute(cilk::reducer_ostream& os, double x) * { * // Perform some significant computation and print the result: - * os << std::asin(x); + * *os << std::asin(x); * } * * int test() @@ -224,6 +224,12 @@ public: return ((*_Pfn)(v)); } + + reducer_ostream& operator*() { return *this; } + reducer_ostream const& operator*() const { return *this; } + + reducer_ostream* operator->() { return this; } + reducer_ostream const* operator->() const { return this; } }; diff --git a/libcilkrts/include/cilk/reducer_string.h b/libcilkrts/include/cilk/reducer_string.h index bb39b168223..9d323271ae2 100644 --- a/libcilkrts/include/cilk/reducer_string.h +++ b/libcilkrts/include/cilk/reducer_string.h @@ -30,8 +30,8 @@ * Purpose: Reducer hyperobject to accumulate a string. * * Classes: reducer_basic_string<Elem, Traits, Alloc> - * reducer_string - convenience typedef for a reducer string of chars - * reducer_wstring - convenience typedef for a reducer string of wchar_t's + * reducer_string - convenience name for a string-of-char reducer + * reducer_wstring - convenience name for a string-of-wchar_t reducer * * Description: * ============ @@ -81,13 +81,13 @@ * extern X myArray[ARRAY_SIZE]; * // ... * - * cilk::hyperobject<cilk::reducer_string> result; + * cilk::reducer_string result; * cilk_for (std::size_t i = 0; i < ARRAY_SIZE; ++i) * { - * result += compute(myArray[i]); + * *result += compute(myArray[i]); * } * - * std::cout << "The result is: " << result.get_value().c_str() << std::endl; + * std::cout << "The result is: " << result.get_value() << std::endl; * * return 0; * } @@ -97,8 +97,8 @@ * ==================== * * 'reducer_string' supports operator+= and append. - *.. - * The the current value of the reducer can be get using the 'get_value' + * + * The the current value of the reducer can be retrieved using the 'get_value' * method. As with most reducers, the 'get_value' method produces deterministic * results only if called before the first spawn after creating a 'hyperobject' * or when all strands spawned since creating the 'hyperobject' have been @@ -204,6 +204,13 @@ public: reducer_basic_string<_Elem, _Traits, _Alloc> &operator+=(_Elem ch); reducer_basic_string<_Elem, _Traits, _Alloc> &operator+=(const _Elem *ptr); reducer_basic_string<_Elem, _Traits, _Alloc> &operator+=(const string_type &right); + + reducer_basic_string& operator*() { return *this; } + reducer_basic_string const& operator*() const { return *this; } + + reducer_basic_string* operator->() { return this; } + reducer_basic_string const* operator->() const { return this; } + }; // class reducer_basic_string ///////////////////////////////////////////////////////////////////////////// diff --git a/libcilkrts/include/internal/cilk_version.h b/libcilkrts/include/internal/cilk_version.h index 59d73d4dd22..d0d3bc051d4 100644 --- a/libcilkrts/include/internal/cilk_version.h +++ b/libcilkrts/include/internal/cilk_version.h @@ -1,6 +1,6 @@ // cilk_version.h // -// Copyright (C) 2009-2011 +// Copyright (C) 2009-2012 // Intel Corporation // // This file is part of the Intel Cilk Plus Library. This library is free @@ -28,9 +28,10 @@ #define VERSION_MAJOR 2 #define VERSION_MINOR 0 -#define VERSION_BUILD 2546 +#define VERSION_BUILD 2856 #define VERSION_REV 0 -#define VERSION_STRING "2,0,2546,0" -#define VERSION_HASH "977cb3e8296a" -#define VERSION_BRANCH "eng" -#define TBB_REV_NUMBER "8650" +#define VERSION_STRING "2,0,2856,0" +#define VERSION_HASH "71912a126cb8" +#define VERSION_BRANCH "v13.0" +#define TBB_REV_NUMBER "" +#define VERSION_YEAR "2012" diff --git a/libcilkrts/include/internal/rev.mk b/libcilkrts/include/internal/rev.mk index f34cc83ff45..574df641ab7 100644 --- a/libcilkrts/include/internal/rev.mk +++ b/libcilkrts/include/internal/rev.mk @@ -1,6 +1,6 @@ ######################################################################### # -# Copyright (C) 2011 +# Copyright (C) 2011-2012 # Intel Corporation # # This file is part of the Intel Cilk Plus Library. This library is free @@ -24,4 +24,4 @@ # <http://www.gnu.org/licenses/>. ########################################################################### -CILK_REVISION = 2546 +CILK_REVISION = 2856 diff --git a/libcilkrts/runtime/cilk-abi-cilk-for.cpp b/libcilkrts/runtime/cilk-abi-cilk-for.cpp index 4fb096d24ac..373ebb16b9f 100644 --- a/libcilkrts/runtime/cilk-abi-cilk-for.cpp +++ b/libcilkrts/runtime/cilk-abi-cilk-for.cpp @@ -111,7 +111,7 @@ template <typename count_t, typename F> inline static void call_cilk_for_loop_body(count_t low, count_t high, F body, void *data, - /* __cilkrts_worker *w, */ + __cilkrts_worker *w, __cilkrts_pedigree *loop_root_pedigree) { // The worker is only valid until the first spawn. Fetch the @@ -119,7 +119,6 @@ void call_cilk_for_loop_body(count_t low, count_t high, // steals. The sf pointer actually points to the *parent's* // __cilkrts_stack_frame, since this function is a non-spawning function // and therefore has no cilk stack frame of its own. - __cilkrts_worker *w = __cilkrts_get_tls_worker(); __cilkrts_stack_frame *sf = w->current_stack_frame; // Save the pedigree node pointed to by the worker. We'll need to restore @@ -131,7 +130,7 @@ void call_cilk_for_loop_body(count_t low, count_t high, // to flatten the tree regardless of the DAG branches in the cilk_for // divide-and-conquer recursion. // - // The rank is initailized to the low index. The user is + // The rank is initialized to the low index. The user is // expected to call __cilkrts_bump_loop_rank at the end of the cilk_for // loop body. __cilkrts_pedigree loop_leaf_pedigree; @@ -156,6 +155,40 @@ void call_cilk_for_loop_body(count_t low, count_t high, w->pedigree.parent = saved_next_pedigree_node; } +/* capture_spawn_arg_stack_frame + * + * Efficiently get the address of the caller's __cilkrts_stack_frame. The + * preconditons are that 'w' is the worker at the time of the call and + * 'w->current_stack_frame' points to the __cilkrts_stack_frame within the + * spawn helper. This function should be called only within the argument list + * of a function that is being spawned because that is the only situation in + * which these preconditions hold. This function returns the worker + * (unchanged) after storing the captured stack frame pointer is stored in the + * sf argument. + * + * The purpose of this function is to get the caller's stack frame in a + * context where the caller's worker is known but its stack frame is not + * necessarily initialized. The "shrink wrap" optimization delays + * initializing the contents of a spawning function's '__cilkrts_stack_frame' + * as well as the 'current_stack_frame' pointer within the worker. By calling + * this function within a spawning function's argument list, we can ensure + * that these initializations have occured but that a detach (which would + * invalidate the worker pointer in the caller) has not yet occured. Once the + * '__cilkrts_stack_frame' has been retrieved in this way, it is stable for the + * remainder of the caller's execution, and becomes an efficient way to get + * the worker (much more efficient than calling '__cilkrts_get_tls_worker()'), + * even after a spawn or sync. + */ +inline __cilkrts_worker* +capture_spawn_arg_stack_frame(__cilkrts_stack_frame* &sf, __cilkrts_worker* w) +{ + // w->current_stack_frame is the spawn helper's stack frame. + // w->current_stack_frame->call_parent is the caller's stack frame. + // return w->current_stack_frame->call_parent; + sf = w->current_stack_frame->call_parent; + return w; +} + /* * cilk_for_recursive * @@ -175,14 +208,9 @@ template <typename count_t, typename F> static void cilk_for_recursive(count_t low, count_t high, F body, void *data, int grain, - /* __cilkrts_worker *w, */ + __cilkrts_worker *w, __cilkrts_pedigree *loop_root_pedigree) { - // The worker is valid only until the first spawn. Fetch the - // __cilkrts_stack_frame out of the worker, since it will be stable across - // steals -/* __cilkrts_stack_frame *sf = w->current_stack_frame; */ - tail_recurse: count_t count = high - low; // Invariant: count > 0, grain >= 1 @@ -190,17 +218,27 @@ tail_recurse: { // Invariant: count >= 2 count_t mid = low + count / 2; + // The worker is valid only until the first spawn and is expensive to + // retrieve (using '__cilkrts_get_tls_worker') after the spawn. The + // '__cilkrts_stack_frame' is more stable, but isn't initialized until + // the first spawn. Thus, we want to grab the address of the + // '__cilkrts_stack_frame' after it is initialized but before the + // spawn detaches. The only place we can do that is within the + // argument list of the spawned function, hence the call to + // capture_spawn_arg_stack_frame(). + __cilkrts_stack_frame *sf; _Cilk_spawn cilk_for_recursive(low, mid, body, data, grain, - /* sf->worker, */ loop_root_pedigree); + capture_spawn_arg_stack_frame(sf, w), + loop_root_pedigree); + w = sf->worker; low = mid; + goto tail_recurse; } // Call the cilk_for loop body lambda function passed in by the compiler to // execute one grain - call_cilk_for_loop_body(low, high, body, data, - /* sf->worker, */ loop_root_pedigree); - + call_cilk_for_loop_body(low, high, body, data, w, loop_root_pedigree); } static void noop() { } @@ -218,9 +256,18 @@ static void noop() { } template <typename count_t, typename F> static void cilk_for_root(F body, void *data, count_t count, int grain) { - __cilkrts_pedigree loop_root_pedigree; - __cilkrts_worker *w; - __cilkrts_stack_frame *sf; + // Pedigree computation: + // + // If the last pedigree node on entry to the _Cilk_for has value X, + // then at the start of each iteration of the loop body, the value of + // the last pedigree node should be 0, the value of the second-to-last + // node should equal the loop counter, and the value of the + // third-to-last node should be X. On return from the _Cilk_for, the + // value of the last pedigree should be incremented to X+2. The + // pedigree within the loop is thus flattened, such that the depth of + // recursion does not affect the results either inside or outside of + // the loop. Note that the pedigree after the loop exists is the same + // as if a single spawn and sync were executed within this function. // TBD: Since the shrink-wrap optimization was turned on in the compiler, // it is not possible to get the current stack frame without actually @@ -231,12 +278,16 @@ static void cilk_for_root(F body, void *data, count_t count, int grain) // Fetch the current worker. From that we can get the current stack frame // which will be constant even if we're stolen - w = __cilkrts_get_tls_worker(); - sf = w->current_stack_frame; + __cilkrts_worker *w = __cilkrts_get_tls_worker(); + __cilkrts_stack_frame *sf = w->current_stack_frame; + + // Decrement the rank by one to undo the pedigree change from the + // _Cilk_spawn + --w->pedigree.rank; - // Save the current worker pedigree into the loop root - --w->pedigree.rank; // Undo change from spawn - loop_root_pedigree = w->pedigree; + // Save the current worker pedigree into loop_root_pedigree, which will be + // the root node for our flattened pedigree. + __cilkrts_pedigree loop_root_pedigree = w->pedigree; // Don't splice the loop_root node in yet. It will be done when we // call the loop body lambda function @@ -247,42 +298,27 @@ static void cilk_for_root(F body, void *data, count_t count, int grain) * Runtime must be started in order to call the grainsize() function. */ int gs = grainsize(grain, count); - if (count > gs) - { - count_t mid = count / 2; - _Cilk_spawn cilk_for_recursive((count_t) 0, mid, body, data, gs, /* w, */ - &loop_root_pedigree); - cilk_for_recursive(mid, count, body, data, gs, /* sf->worker, */ - &loop_root_pedigree); - - // We must sync before touching the worker below - _Cilk_sync; - - // Need to refetch the worker. The loop body (or something it calls) - // may have included spawns, or the continuation after the cilk_spawn - // above may have been stolen, so we can't assume we're on the same - // worker - w = sf->worker; + cilk_for_recursive((count_t) 0, count, body, data, gs, w, + &loop_root_pedigree); - // Restore the pedigree in the worker. The rank will be bumped - // by the return - w->pedigree = loop_root_pedigree; - } - else - { - // Call the cilk_for loop body lambda function to execute over the - // entire range - call_cilk_for_loop_body((count_t)0, count, body, data, /* w, */ - &loop_root_pedigree); - } + // Need to refetch the worker after calling a spawning function. + w = sf->worker; - // If this is an optimized build, then the compiler will have optimized - // out the increment of the worker's pedigree in the implied sync. We - // need to add one to make the pedigree_loop test work correctly - if (CILKRTS_OPTIMIZED) - { - ++sf->worker->pedigree.rank; - } + // Restore the pedigree in the worker. + w->pedigree = loop_root_pedigree; + + // Bump the worker pedigree. + ++w->pedigree.rank; + + // Implicit sync will increment the pedigree leaf rank again, for a total + // of two increments. If the noop spawn above is removed, then we'll need + // to re-enable the following code: +// // If this is an optimized build, then the compiler will have optimized +// // out the increment of the worker's pedigree in the implied sync. We +// // need to add one to make the pedigree_loop test work correctly. +// #if CILKRTS_OPTIMIZED +// ++sf->worker->pedigree.rank; +// #endif } // Use extern "C" to suppress name mangling of __cilkrts_cilk_for_32 and diff --git a/libcilkrts/runtime/except-gcc.cpp b/libcilkrts/runtime/except-gcc.cpp index 79cba338932..d577428e5a4 100644 --- a/libcilkrts/runtime/except-gcc.cpp +++ b/libcilkrts/runtime/except-gcc.cpp @@ -545,6 +545,11 @@ struct pending_exception_info *__cilkrts_get_exception(__cilkrts_worker *w, extern "C" void __attribute__((nonnull)) __cilkrts_gcc_rethrow(__cilkrts_stack_frame *sf) { +#ifdef __CYGWIN__ + // Cygwin doesn't support exceptions, so _Unwind_Resume isn't available + // Which means we can't support exceptions either + __cilkrts_bug("The Cygwin implementation of the Intel Cilk Plus runtime doesn't support exceptions\n"); +#else if (sf->except_data) { #if CILK_LIB_DEBUG CILK_ASSERT(std::uncaught_exception()); @@ -553,6 +558,8 @@ void __attribute__((nonnull)) __cilkrts_gcc_rethrow(__cilkrts_stack_frame *sf) } else { throw; } +#endif // __CYGWIN__ } /* End except-gcc.cpp */ + diff --git a/libcilkrts/runtime/global_state.cpp b/libcilkrts/runtime/global_state.cpp index dd90f61e918..8bdef33556c 100644 --- a/libcilkrts/runtime/global_state.cpp +++ b/libcilkrts/runtime/global_state.cpp @@ -51,9 +51,6 @@ // initialized. int cilkg_user_settable_values_initialized = false; -// Pointer to the global state singleton. -extern "C" global_state_t *cilkg_singleton_ptr = NULL; - namespace { // Single copy of the global state. Zero-filled until @@ -65,9 +62,17 @@ global_state_t global_state_singleton = sizeof(void *), // addr_size }; -// __cilkrts_global_state is exported and referenced by the debugger. -// The debugger expects it to be valid when the module loads. -extern "C" global_state_t *__cilkrts_global_state = &global_state_singleton; + +// Variables that need to export C-style names +extern "C" +{ + // Pointer to the global state singleton. + global_state_t *cilkg_singleton_ptr = NULL; + + // __cilkrts_global_state is exported and referenced by the debugger. + // The debugger expects it to be valid when the module loads. + global_state_t *__cilkrts_global_state = &global_state_singleton; +} // Returns true if 'a' and 'b' are equal null-terminated strings inline bool strmatch(const char* a, const char* b) @@ -232,7 +237,11 @@ int set_param_imp(global_state_t* g, const CHAR_T* param, const CHAR_T* value) if (cilkg_singleton_ptr) return __CILKRTS_SET_PARAM_LATE; + // Fetch the number of cores. There must be at last 1, since we're + // executing on *something*, aren't we!? int hardware_cpu_count = __cilkrts_hardware_cpu_count(); + CILK_ASSERT(hardware_cpu_count > 0); + int max_cpu_count = 16 * hardware_cpu_count; if (__cilkrts_running_under_sequential_ptool()) { @@ -251,6 +260,8 @@ int set_param_imp(global_state_t* g, const CHAR_T* param, const CHAR_T* value) // // Sets the number of slots allocated for user worker threads int hardware_cpu_count = __cilkrts_hardware_cpu_count(); + CILK_ASSERT (hardware_cpu_count > 0); + return store_int(&g->max_user_workers, value, 1, 16 * hardware_cpu_count); } @@ -289,6 +300,10 @@ int set_param_imp(global_state_t* g, const CHAR_T* param, const CHAR_T* value) // ** UNDOCUMENTED ** // // Sets the size (in bytes) of the stacks that Cilk creates. + // Can only be set before the runtime starts. + if (cilkg_singleton_ptr) + return __CILKRTS_SET_PARAM_LATE; + // Maximum value that can be parsed is MAX_INT (32-bit). int ret = store_int<size_t>(&g->stack_size, value, 0, INT_MAX); @@ -348,7 +363,11 @@ global_state_t* cilkg_get_user_settable_values() // All fields will be zero until set. In particular std::memset(g, 0, sizeof(global_state_t)); + // Fetch the number of cores. There must be at last 1, since we're + // executing on *something*, aren't we!? int hardware_cpu_count = __cilkrts_hardware_cpu_count(); + CILK_ASSERT(hardware_cpu_count > 0); + bool under_ptool = __cilkrts_running_under_sequential_ptool(); if (under_ptool) hardware_cpu_count = 1; diff --git a/libcilkrts/runtime/os-unix.c b/libcilkrts/runtime/os-unix.c index 21ea710acc1..417a4bf56bb 100644 --- a/libcilkrts/runtime/os-unix.c +++ b/libcilkrts/runtime/os-unix.c @@ -45,8 +45,10 @@ # include <sys/sysctl.h> // Uses sysconf(_SC_NPROCESSORS_ONLN) in verbose output #elif defined __FreeBSD__ +#elif defined __CYGWIN__ +// Cygwin on Windows - no additional include files #else -# error Unsupported OS +# error "Unsupported OS" #endif #include <stdarg.h> @@ -323,8 +325,14 @@ COMMON_SYSDEP int __cilkrts_hardware_cpu_count(void) assert((unsigned)count == count); return count; -#elif defined __FreeBSD__ - return sysconf(_SC_NPROCESSORS_ONLN); +#elif defined __FreeBSD__ || defined __CYGWIN__ + int ncores = sysconf(_SC_NPROCESSORS_ONLN); + + return ncores; + // Just get the number of processors +// return sysconf(_SC_NPROCESSORS_ONLN); +#else +#error "Unknown architecture" #endif } diff --git a/libcilkrts/runtime/sysdep-unix.c b/libcilkrts/runtime/sysdep-unix.c index 8ef26eb980f..cb021e44d5f 100644 --- a/libcilkrts/runtime/sysdep-unix.c +++ b/libcilkrts/runtime/sysdep-unix.c @@ -52,6 +52,12 @@ #include "cilk-ittnotify.h" #include <stddef.h> + +#ifdef __CYGWIN__ +// On Cygwin, string.h doesnt declare strcasecmp if __STRICT_ANSI__ is defined +# undef __STRICT_ANSI__ +#endif + #include <string.h> #include <pthread.h> #include <unistd.h> @@ -69,6 +75,7 @@ # define MAP_ANONYMOUS MAP_ANON #endif + static void internal_enforce_global_visibility(); struct global_sysdep_state @@ -822,9 +829,14 @@ void dummy_function() { } */ static const char *get_runtime_path () { +#ifdef __CYGWIN__ + // Cygwin doesn't support dladdr, which sucks + return "unknown"; +#else Dl_info info; if (0 == dladdr(dummy_function, &info)) return "unknown"; return info.dli_fname; +#endif } /* if the environment variable, CILK_VERSION, is defined, writes the version |