/* used anamorphically: section, nsections */
#define OUTER_PERSECTION_BASE(zero,n, sect) \
- ((zero) + sect * (((n)-(zero) + NSECTIONS-1) / NSECTIONS))
-#define OUTER(v,zero,n, precomp) \
- for ((v)= OUTER_PERSECTION_BASE((zero),(n), section); \
- precomp, \
- (v) < OUTER_PERSECTION_BASE((zero),(n), section + 1) && (v) < (n); \
+ ((zero) + (sect) * (((n)-(zero) + NSECTIONS-1) / NSECTIONS))
+#define OUTER(v,zero,n, precomp) \
+ for ((v)= OUTER_PERSECTION_BASE((zero),(n), (section)); \
+ precomp, \
+ (v) < OUTER_PERSECTION_BASE((zero),(n), (section) + 1) && (v) < (n); \
(v)++)
+/*
+ * OUTER is a loop constructor like INNER (see mgraph.h).
+ *
+ * Constraints on its use:
+ * - must be in exactly one loop of particular function
+ * - function must not modify anything other than
+ * its return value (for cost computation functions, COST()) or
+ * its designated output (for precomputation functions, PRECOMP())
+ * and in the latter case it may not read other parts of its output
+ * - function must of course be reentrant
+ */
+
#define nsections NSECTIONS
typedef void Computation(const struct Vertices *vertices,
Computation *separately,
Computation *combine,
size_t secdatasz, void *gendata);
+ /* nsections copies of the computation `separately' are run in parallel
+ * with different values of `section' from 0 to nsections-1.
+ * Each copy is passed the same gendata as passed to inparallel.
+ * Each copy gets its own data block (struct aligned) of size
+ * secdatasz, passed as secdata, uninitialised on entry.
+ * After all the copies have finished, `combine' is invoked
+ * nsections times sequentially, with the same sets of arguments.
+ * inparallel is NOT itself reentrant.
+ */
+
+void inparallel_barrier(void);
#endif /*PARALLEL_H*/