207 int Nt = omp_get_max_threads();
208 ptrdiff_t * Anmemb =
ta_malloc(
"Anmemb", ptrdiff_t, Nt);
209 ptrdiff_t * Anmemb_old =
ta_malloc(
"Anmemb_old", ptrdiff_t, Nt);
211 void ** Abase_store =
ta_malloc(
"Abase",
void *, Nt);
212 void ** Atmp_store =
ta_malloc(
"Atmp",
void *, Nt);
213 void ** Abase = Abase_store;
214 void ** Atmp = Atmp_store;
224 tmp =
mymalloc(
"qsort",2*nmemb*
sizeof(
void *) + size);
226 tmp =
mymalloc(
"qsort", size * nmemb);
230 int tid = omp_get_thread_num();
232 int Nt = omp_get_num_threads();
235 ptrdiff_t start = tid * nmemb / Nt;
236 ptrdiff_t end = (tid + 1) * nmemb / Nt;
238 Anmemb[tid] = end - start;
239 Anmemb_old[tid] = end - start;
240 Abase[tid] = ((
char*) base) + start * size;
241 Atmp[tid] = ((
char*) tmp) + start * size;
244 p.
t = ((
char **) Atmp)[tid];
253 char *ip = (
char *) Abase[tid];
254 void **tp = (
void **) ((
char *)tmp + (nmemb + start)*
sizeof (
void *));
256 void *end = (
void *) (tp + Anmemb[tid]);
258 while ((
void *)
t < end)
263 p.s =
sizeof (
void *);
266 Atmp[tid] = ((
char*) tmp) + start * p.s;
267 p.t = ((
char **)Atmp)[tid];
271 if ((size & (
sizeof (uint32_t) - 1)) == 0
272 && ((
char *) base - (
char *) 0) % __alignof__ (uint32_t) == 0)
274 if (size ==
sizeof (uint32_t))
276 else if (size ==
sizeof (uint64_t)
277 && ((
char *) base - (
char *) 0) % __alignof__ (uint64_t) == 0)
279 else if ((size & (
sizeof (
unsigned long) - 1)) == 0
280 && ((
char *) base - (
char *) 0)
281 % __alignof__ (
unsigned long) == 0)
289 for (sep = 1; sep < Nt; sep *=2 ) {
290 int color = tid / sep;
294 printf(
"sep = %d Abase[0] %p base %p, Atmp[0] %p tmp %p\n",
295 sep, Abase[0], base, Atmp[0], tmp);
296 printf(
"base 73134 = %d 73135 = %d\n", ((
int*) base)[73134], ((
int*) base)[73135]);
297 printf(
"tmp 73134 = %d 73135 = %d\n", ((
int*) tmp )[73134], ((
int*) tmp )[73135]);
302 if(key == 0 && color % 2 == 0) {
303 int nextT = tid + sep;
308 merge(Abase[tid], Anmemb[tid], NULL, 0, Atmp[tid], p.s, compar, indirect);
311 printf(
"%d + %d merging with %td/%td:%td %td/%td:%td\n", tid, nextT,
312 ((
char*)Abase[tid] - (
char*) base) / size,
313 ((
char*)Abase[tid] - (
char*) tmp) / size,
315 ((
char*)Abase[nextT] - (
char*) base) / size,
316 ((
char*)Abase[nextT] - (
char*) tmp) / size,
319 merge(Abase[tid], Anmemb[tid], Abase[nextT], Anmemb[nextT], Atmp[tid], p.s, compar, indirect);
321 Anmemb[tid] = Anmemb[tid] + Anmemb[nextT];
337 if((!indirect && Abase[0] != base)
338 || (indirect && Abase[0] != (
char *) tmp + nmemb *
sizeof(
void *))) {
339 memmove(Atmp[tid], Abase[tid], Anmemb_old[tid] * p.s);
354 void **tp = (
void **) ((
char *) tmp + nmemb *
sizeof (
void *));
355 void *tmp_storage = (
void *) (tp + nmemb);
356 for (i = 0, ip = (
char *) base; i < nmemb; i++, ip += size)
357 if ((kp = ((
char **)tp)[i]) != ip)
361 memcpy (tmp_storage, ip, size);
364 size_t k = (kp - (
char *) base) / size;
366 memcpy (jp, kp, size);
369 kp = ((
char **)tp)[k];
373 memcpy (jp, tmp_storage, size);
#define mymalloc(name, size)
#define ta_malloc(name, type, nele)
static void msort_with_tmp(const struct msort_param *p, void *b, size_t n)
static void merge(void *base1, size_t nmemb1, void *base2, size_t nmemb2, void *output, size_t size, int(*compar)(const void *, const void *), int indirect)