60 b2 = (
char *) b + (n1 * p->
s);
66 const size_t s = p->
s;
71 while (n1 > 0 && n2 > 0)
73 if ((*cmp) (b1, b2) <= 0)
75 *(uint32_t *) tmp = *(uint32_t *) b1;
76 b1 +=
sizeof (uint32_t);
81 *(uint32_t *) tmp = *(uint32_t *) b2;
82 b2 +=
sizeof (uint32_t);
85 tmp +=
sizeof (uint32_t);
89 while (n1 > 0 && n2 > 0)
91 if ((*cmp) (b1, b2) <= 0)
93 *(uint64_t *) tmp = *(uint64_t *) b1;
94 b1 +=
sizeof (uint64_t);
99 *(uint64_t *) tmp = *(uint64_t *) b2;
100 b2 +=
sizeof (uint64_t);
103 tmp +=
sizeof (uint64_t);
107 while (n1 > 0 && n2 > 0)
109 unsigned long *tmpl = (
unsigned long *) tmp;
113 if ((*cmp) (b1, b2) <= 0)
115 bl = (
unsigned long *) b1;
121 bl = (
unsigned long *) b2;
125 while (tmpl < (
unsigned long *) tmp)
130 while (n1 > 0 && n2 > 0)
132 if ((*cmp) (*(
const void **) b1, *(
const void **) b2) <= 0)
134 *(
void **) tmp = *(
void **) b1;
135 b1 +=
sizeof (
void *);
140 *(
void **) tmp = *(
void **) b2;
141 b2 +=
sizeof (
void *);
144 tmp +=
sizeof (
void *);
148 while (n1 > 0 && n2 > 0)
150 if ((*cmp) (b1, b2) <= 0)
152 tmp = (
char *) memcpy (tmp, b1, s) + s;
158 tmp = (
char *) memcpy (tmp, b2, s) + s;
167 memcpy (tmp, b1, n1 * s);
168 memcpy (b, p->
t, (n - n2) * s);
174 static void merge(
void * base1,
size_t nmemb1,
void * base2,
size_t nmemb2,
void * output,
size_t size,
175 int(*compar)(
const void *,
const void *),
int indirect) {
176 char * p1 = (
char *) base1;
177 char * p2 = (
char *) base2;
178 char * po = (
char *) output;
179 char * s1 = p1 + nmemb1 * size, *s2 = p2 + nmemb2 * size;
180 while(p1 < s1 && p2 < s2) {
183 cmp = compar(*(
void **)p1, *(
void **)p2);
186 cmp = compar(p1, p2);
189 memcpy(po, p1, size);
192 memcpy(po, p2, size);
198 memcpy(po, p1, s1 - p1);
201 memcpy(po, p2, s2 - p2);
206 int(*compar)(
const void *,
const void *)) {
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)
int(* __compar_fn_t)(const void *, const void *)
void qsort_openmp(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *))
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)