aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBalaji V. Iyer <balaji.v.iyer@intel.com>2012-12-28 23:50:07 +0000
committerBalaji V. Iyer <balaji.v.iyer@intel.com>2012-12-28 23:50:07 +0000
commite3e551a667a641fadf4a67dabe48deb78d91c446 (patch)
tree303275ad3fd846a48b82e00ab210ebdbd82ccecd
parent20a71961b2e317cce94b64311a5dcc46b6f376b1 (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.cilkplus20
-rw-r--r--libcilkrts/include/cilk/cilk_api.h20
-rw-r--r--libcilkrts/include/cilk/common.h3
-rw-r--r--libcilkrts/include/cilk/reducer.h16
-rw-r--r--libcilkrts/include/cilk/reducer_list.h30
-rw-r--r--libcilkrts/include/cilk/reducer_max.h20
-rw-r--r--libcilkrts/include/cilk/reducer_min.h22
-rw-r--r--libcilkrts/include/cilk/reducer_opadd.h36
-rw-r--r--libcilkrts/include/cilk/reducer_opand.h22
-rw-r--r--libcilkrts/include/cilk/reducer_opor.h21
-rw-r--r--libcilkrts/include/cilk/reducer_opxor.h11
-rw-r--r--libcilkrts/include/cilk/reducer_ostream.h8
-rw-r--r--libcilkrts/include/cilk/reducer_string.h21
-rw-r--r--libcilkrts/include/internal/cilk_version.h13
-rw-r--r--libcilkrts/include/internal/rev.mk4
-rw-r--r--libcilkrts/runtime/cilk-abi-cilk-for.cpp146
-rw-r--r--libcilkrts/runtime/except-gcc.cpp7
-rw-r--r--libcilkrts/runtime/global_state.cpp31
-rw-r--r--libcilkrts/runtime/os-unix.c14
-rw-r--r--libcilkrts/runtime/sysdep-unix.c12
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