diff --git a/libgomp/libgomp.h b/libgomp/libgomp.h index 33a9591285f..023d8a8c1df 100644 --- a/libgomp/libgomp.h +++ b/libgomp/libgomp.h @@ -257,6 +257,30 @@ struct gomp_doacross_work_share unsigned int shift_counts[]; }; +/* Like struct gomp_work_share, but only the 1st cacheline of it plus + flexible array at the end. + Keep in sync with struct gomp_work_share. */ +struct gomp_work_share_1st_cacheline +{ + enum gomp_schedule_type sched; + int mode; + union { + struct { + long chunk_size, end, incr; + }; + struct { + unsigned long long chunk_size_ull, end_ull, incr_ull; + }; + }; + union { + unsigned *ordered_team_ids; + struct gomp_doacross_work_share *doacross; + }; + unsigned ordered_num_used, ordered_owner, ordered_cur; + struct gomp_work_share *next_alloc; + char pad[]; +}; + struct gomp_work_share { /* This member records the SCHEDULE clause to be used for this construct. @@ -324,7 +348,12 @@ struct gomp_work_share are in a different cache line. */ /* This lock protects the update of the following members. */ +#ifdef GOMP_HAVE_EFFICIENT_ALIGNED_ALLOC gomp_mutex_t lock __attribute__((aligned (64))); +#else + char pad[64 - offsetof (struct gomp_work_share_1st_cacheline, pad)]; + gomp_mutex_t lock; +#endif /* This is the count of the number of threads that have exited the work share construct. If the construct was marked nowait, they have moved on @@ -362,6 +391,12 @@ struct gomp_work_share unsigned inline_ordered_team_ids[0]; }; +extern char gomp_workshare_struct_check1 + [offsetof (struct gomp_work_share_1st_cacheline, next_alloc) + == offsetof (struct gomp_work_share, next_alloc) ? 1 : -1]; +extern char gomp_workshare_struct_check2 + [offsetof (struct gomp_work_share, lock) == 64 ? 1 : -1]; + /* This structure contains all of the thread-local data associated with a thread team. This is the data that must be saved when a thread encounters a nested PARALLEL construct. */ diff --git a/libgomp/work.c b/libgomp/work.c index 9d63eec9832..bf2559155f1 100644 --- a/libgomp/work.c +++ b/libgomp/work.c @@ -191,7 +191,12 @@ gomp_work_share_start (size_t ordered) /* Work sharing constructs can be orphaned. */ if (team == NULL) { +#ifdef GOMP_HAVE_EFFICIENT_ALIGNED_ALLOC + ws = gomp_aligned_alloc (__alignof (struct gomp_work_share), + sizeof (*ws)); +#else ws = gomp_malloc (sizeof (*ws)); +#endif gomp_init_work_share (ws, ordered, 1); thr->ts.work_share = ws; return true;