With the introduction of the USE_TLS option in openblas 0.3.4, threads created by packages loading openblas libraries are affected by a glibc bug described here:
https://sourceware.org/bugzilla/show_bug.cgi?id=11787
The ongoing discussion in openblas:
https://github.com/xianyi/OpenBLAS/issues/1936
Example workarounds used by other projects that inspired this one:
https://github.com/rust-lang/rust/issues/6233
https://github.com/rust-lang/rust/pull/11885
https://bugs.openjdk.java.net/browse/JDK-8225498
... | ... |
@@ -54,6 +54,16 @@ struct loop_data{ |
54 | 54 |
int start_row; |
55 | 55 |
int end_row; |
56 | 56 |
}; |
57 |
+ |
|
58 |
+#ifdef __linux__ |
|
59 |
+#include <features.h> |
|
60 |
+#ifdef __GLIBC__ |
|
61 |
+#ifdef __GLIBC_PREREQ && __GLIBC_PREREQ(2, 15) |
|
62 |
+#define INFER_MIN_STACKSIZE 1 |
|
63 |
+#endif |
|
64 |
+#endif |
|
65 |
+#endif |
|
66 |
+ |
|
57 | 67 |
#endif |
58 | 68 |
|
59 | 69 |
|
... | ... |
@@ -108,11 +118,17 @@ SEXP R_subColSummarize_avg_log(SEXP RMatrix, SEXP R_rowIndexList){ |
108 | 118 |
double chunk_size_d, chunk_tot_d; |
109 | 119 |
char *nthreads; |
110 | 120 |
pthread_attr_t attr; |
121 |
+ /* Initialize thread attribute */ |
|
122 |
+ pthread_attr_init(&attr); |
|
111 | 123 |
pthread_t *threads; |
112 | 124 |
struct loop_data *args; |
113 | 125 |
void *status; |
114 | 126 |
#ifdef PTHREAD_STACK_MIN |
115 |
- size_t stacksize = PTHREAD_STACK_MIN + 0x4000; |
|
127 |
+#ifdef INFER_MIN_STACKSIZE |
|
128 |
+ size_t stacksize = __pthread_get_minstack(&attr) + sysconf(_SC_PAGE_SIZE); |
|
129 |
+#else |
|
130 |
+ size_t stacksize = PTHREAD_STACK_MIN + sysconf(_SC_PAGE_SIZE); |
|
131 |
+#endif |
|
116 | 132 |
#else |
117 | 133 |
size_t stacksize = 0x8000; |
118 | 134 |
#endif |
... | ... |
@@ -136,8 +152,7 @@ SEXP R_subColSummarize_avg_log(SEXP RMatrix, SEXP R_rowIndexList){ |
136 | 152 |
} |
137 | 153 |
threads = (pthread_t *) Calloc(num_threads, pthread_t); |
138 | 154 |
|
139 |
- /* Initialize and set thread detached attribute */ |
|
140 |
- pthread_attr_init(&attr); |
|
155 |
+ /* Set thread detached attribute */ |
|
141 | 156 |
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); |
142 | 157 |
pthread_attr_setstacksize (&attr, stacksize); |
143 | 158 |
/* this code works out how many threads to use and allocates ranges of subColumns to each thread */ |
... | ... |
@@ -276,11 +291,17 @@ SEXP R_subColSummarize_log_avg(SEXP RMatrix, SEXP R_rowIndexList){ |
276 | 291 |
double chunk_size_d, chunk_tot_d; |
277 | 292 |
char *nthreads; |
278 | 293 |
pthread_attr_t attr; |
294 |
+ /* Initialize thread attribute */ |
|
295 |
+ pthread_attr_init(&attr); |
|
279 | 296 |
pthread_t *threads; |
280 | 297 |
struct loop_data *args; |
281 | 298 |
void *status; |
282 | 299 |
#ifdef PTHREAD_STACK_MIN |
283 |
- size_t stacksize = PTHREAD_STACK_MIN + 0x4000; |
|
300 |
+#ifdef INFER_MIN_STACKSIZE |
|
301 |
+ size_t stacksize = __pthread_get_minstack(&attr) + sysconf(_SC_PAGE_SIZE); |
|
302 |
+#else |
|
303 |
+ size_t stacksize = PTHREAD_STACK_MIN + sysconf(_SC_PAGE_SIZE); |
|
304 |
+#endif |
|
284 | 305 |
#else |
285 | 306 |
size_t stacksize = 0x8000; |
286 | 307 |
#endif |
... | ... |
@@ -304,8 +325,7 @@ SEXP R_subColSummarize_log_avg(SEXP RMatrix, SEXP R_rowIndexList){ |
304 | 325 |
} |
305 | 326 |
threads = (pthread_t *) Calloc(num_threads, pthread_t); |
306 | 327 |
|
307 |
- /* Initialize and set thread detached attribute */ |
|
308 |
- pthread_attr_init(&attr); |
|
328 |
+ /* Set thread detached attribute */ |
|
309 | 329 |
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); |
310 | 330 |
pthread_attr_setstacksize (&attr, stacksize); |
311 | 331 |
|
... | ... |
@@ -447,11 +467,17 @@ SEXP R_subColSummarize_avg(SEXP RMatrix, SEXP R_rowIndexList){ |
447 | 467 |
double chunk_size_d, chunk_tot_d; |
448 | 468 |
char *nthreads; |
449 | 469 |
pthread_attr_t attr; |
470 |
+ /* Initialize thread attribute */ |
|
471 |
+ pthread_attr_init(&attr); |
|
450 | 472 |
pthread_t *threads; |
451 | 473 |
struct loop_data *args; |
452 | 474 |
void *status; |
453 | 475 |
#ifdef PTHREAD_STACK_MIN |
454 |
- size_t stacksize = PTHREAD_STACK_MIN + 0x4000; |
|
476 |
+#ifdef INFER_MIN_STACKSIZE |
|
477 |
+ size_t stacksize = __pthread_get_minstack(&attr) + sysconf(_SC_PAGE_SIZE); |
|
478 |
+#else |
|
479 |
+ size_t stacksize = PTHREAD_STACK_MIN + sysconf(_SC_PAGE_SIZE); |
|
480 |
+#endif |
|
455 | 481 |
#else |
456 | 482 |
size_t stacksize = 0x8000; |
457 | 483 |
#endif |
... | ... |
@@ -475,8 +501,7 @@ SEXP R_subColSummarize_avg(SEXP RMatrix, SEXP R_rowIndexList){ |
475 | 501 |
} |
476 | 502 |
threads = (pthread_t *) Calloc(num_threads, pthread_t); |
477 | 503 |
|
478 |
- /* Initialize and set thread detached attribute */ |
|
479 |
- pthread_attr_init(&attr); |
|
504 |
+ /* Set thread detached attribute */ |
|
480 | 505 |
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); |
481 | 506 |
pthread_attr_setstacksize (&attr, stacksize); |
482 | 507 |
|
... | ... |
@@ -619,11 +644,17 @@ SEXP R_subColSummarize_biweight_log(SEXP RMatrix, SEXP R_rowIndexList){ |
619 | 644 |
double chunk_size_d, chunk_tot_d; |
620 | 645 |
char *nthreads; |
621 | 646 |
pthread_attr_t attr; |
647 |
+ /* Initialize thread attribute */ |
|
648 |
+ pthread_attr_init(&attr); |
|
622 | 649 |
pthread_t *threads; |
623 | 650 |
struct loop_data *args; |
624 | 651 |
void *status; |
625 | 652 |
#ifdef PTHREAD_STACK_MIN |
626 |
- size_t stacksize = PTHREAD_STACK_MIN + 0x4000; |
|
653 |
+#ifdef INFER_MIN_STACKSIZE |
|
654 |
+ size_t stacksize = __pthread_get_minstack(&attr) + sysconf(_SC_PAGE_SIZE); |
|
655 |
+#else |
|
656 |
+ size_t stacksize = PTHREAD_STACK_MIN + sysconf(_SC_PAGE_SIZE); |
|
657 |
+#endif |
|
627 | 658 |
#else |
628 | 659 |
size_t stacksize = 0x8000; |
629 | 660 |
#endif |
... | ... |
@@ -648,8 +679,7 @@ SEXP R_subColSummarize_biweight_log(SEXP RMatrix, SEXP R_rowIndexList){ |
648 | 679 |
} |
649 | 680 |
threads = (pthread_t *) Calloc(num_threads, pthread_t); |
650 | 681 |
|
651 |
- /* Initialize and set thread detached attribute */ |
|
652 |
- pthread_attr_init(&attr); |
|
682 |
+ /* Set thread detached attribute */ |
|
653 | 683 |
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); |
654 | 684 |
pthread_attr_setstacksize (&attr, stacksize); |
655 | 685 |
/* this code works out how many threads to use and allocates ranges of subColumns to each thread */ |
... | ... |
@@ -790,11 +820,17 @@ SEXP R_subColSummarize_biweight(SEXP RMatrix, SEXP R_rowIndexList){ |
790 | 820 |
double chunk_size_d, chunk_tot_d; |
791 | 821 |
char *nthreads; |
792 | 822 |
pthread_attr_t attr; |
823 |
+ /* Initialize thread attribute */ |
|
824 |
+ pthread_attr_init(&attr); |
|
793 | 825 |
pthread_t *threads; |
794 | 826 |
struct loop_data *args; |
795 | 827 |
void *status; |
796 | 828 |
#ifdef PTHREAD_STACK_MIN |
797 |
- size_t stacksize = PTHREAD_STACK_MIN + 0x4000; |
|
829 |
+#ifdef INFER_MIN_STACKSIZE |
|
830 |
+ size_t stacksize = __pthread_get_minstack(&attr) + sysconf(_SC_PAGE_SIZE); |
|
831 |
+#else |
|
832 |
+ size_t stacksize = PTHREAD_STACK_MIN + sysconf(_SC_PAGE_SIZE); |
|
833 |
+#endif |
|
798 | 834 |
#else |
799 | 835 |
size_t stacksize = 0x8000; |
800 | 836 |
#endif |
... | ... |
@@ -818,8 +854,7 @@ SEXP R_subColSummarize_biweight(SEXP RMatrix, SEXP R_rowIndexList){ |
818 | 854 |
} |
819 | 855 |
threads = (pthread_t *) Calloc(num_threads, pthread_t); |
820 | 856 |
|
821 |
- /* Initialize and set thread detached attribute */ |
|
822 |
- pthread_attr_init(&attr); |
|
857 |
+ /* Set thread detached attribute */ |
|
823 | 858 |
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); |
824 | 859 |
pthread_attr_setstacksize (&attr, stacksize); |
825 | 860 |
|
... | ... |
@@ -962,11 +997,17 @@ SEXP R_subColSummarize_median_log(SEXP RMatrix, SEXP R_rowIndexList){ |
962 | 997 |
double chunk_size_d, chunk_tot_d; |
963 | 998 |
char *nthreads; |
964 | 999 |
pthread_attr_t attr; |
1000 |
+ /* Initialize thread attribute */ |
|
1001 |
+ pthread_attr_init(&attr); |
|
965 | 1002 |
pthread_t *threads; |
966 | 1003 |
struct loop_data *args; |
967 | 1004 |
void *status; |
968 | 1005 |
#ifdef PTHREAD_STACK_MIN |
969 |
- size_t stacksize = PTHREAD_STACK_MIN + 0x4000; |
|
1006 |
+#ifdef INFER_MIN_STACKSIZE |
|
1007 |
+ size_t stacksize = __pthread_get_minstack(&attr) + sysconf(_SC_PAGE_SIZE); |
|
1008 |
+#else |
|
1009 |
+ size_t stacksize = PTHREAD_STACK_MIN + sysconf(_SC_PAGE_SIZE); |
|
1010 |
+#endif |
|
970 | 1011 |
#else |
971 | 1012 |
size_t stacksize = 0x8000; |
972 | 1013 |
#endif |
... | ... |
@@ -990,8 +1031,7 @@ SEXP R_subColSummarize_median_log(SEXP RMatrix, SEXP R_rowIndexList){ |
990 | 1031 |
} |
991 | 1032 |
threads = (pthread_t *) Calloc(num_threads, pthread_t); |
992 | 1033 |
|
993 |
- /* Initialize and set thread detached attribute */ |
|
994 |
- pthread_attr_init(&attr); |
|
1034 |
+ /* Set thread detached attribute */ |
|
995 | 1035 |
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); |
996 | 1036 |
pthread_attr_setstacksize (&attr, stacksize); |
997 | 1037 |
|
... | ... |
@@ -1132,11 +1172,17 @@ SEXP R_subColSummarize_log_median(SEXP RMatrix, SEXP R_rowIndexList){ |
1132 | 1172 |
double chunk_size_d, chunk_tot_d; |
1133 | 1173 |
char *nthreads; |
1134 | 1174 |
pthread_attr_t attr; |
1175 |
+ /* Initialize thread attribute */ |
|
1176 |
+ pthread_attr_init(&attr); |
|
1135 | 1177 |
pthread_t *threads; |
1136 | 1178 |
struct loop_data *args; |
1137 | 1179 |
void *status; |
1138 | 1180 |
#ifdef PTHREAD_STACK_MIN |
1139 |
- size_t stacksize = PTHREAD_STACK_MIN + 0x4000; |
|
1181 |
+#ifdef INFER_MIN_STACKSIZE |
|
1182 |
+ size_t stacksize = __pthread_get_minstack(&attr) + sysconf(_SC_PAGE_SIZE); |
|
1183 |
+#else |
|
1184 |
+ size_t stacksize = PTHREAD_STACK_MIN + sysconf(_SC_PAGE_SIZE); |
|
1185 |
+#endif |
|
1140 | 1186 |
#else |
1141 | 1187 |
size_t stacksize = 0x8000; |
1142 | 1188 |
#endif |
... | ... |
@@ -1160,8 +1206,7 @@ SEXP R_subColSummarize_log_median(SEXP RMatrix, SEXP R_rowIndexList){ |
1160 | 1206 |
} |
1161 | 1207 |
threads = (pthread_t *) Calloc(num_threads, pthread_t); |
1162 | 1208 |
|
1163 |
- /* Initialize and set thread detached attribute */ |
|
1164 |
- pthread_attr_init(&attr); |
|
1209 |
+ /* Set thread detached attribute */ |
|
1165 | 1210 |
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); |
1166 | 1211 |
pthread_attr_setstacksize (&attr, stacksize); |
1167 | 1212 |
|
... | ... |
@@ -1301,11 +1346,17 @@ SEXP R_subColSummarize_median(SEXP RMatrix, SEXP R_rowIndexList){ |
1301 | 1346 |
double chunk_size_d, chunk_tot_d; |
1302 | 1347 |
char *nthreads; |
1303 | 1348 |
pthread_attr_t attr; |
1349 |
+ /* Initialize thread attribute */ |
|
1350 |
+ pthread_attr_init(&attr); |
|
1304 | 1351 |
pthread_t *threads; |
1305 | 1352 |
struct loop_data *args; |
1306 | 1353 |
void *status; |
1307 | 1354 |
#ifdef PTHREAD_STACK_MIN |
1308 |
- size_t stacksize = PTHREAD_STACK_MIN + 0x4000; |
|
1355 |
+#ifdef INFER_MIN_STACKSIZE |
|
1356 |
+ size_t stacksize = __pthread_get_minstack(&attr) + sysconf(_SC_PAGE_SIZE); |
|
1357 |
+#else |
|
1358 |
+ size_t stacksize = PTHREAD_STACK_MIN + sysconf(_SC_PAGE_SIZE); |
|
1359 |
+#endif |
|
1309 | 1360 |
#else |
1310 | 1361 |
size_t stacksize = 0x8000; |
1311 | 1362 |
#endif |
... | ... |
@@ -1329,8 +1380,7 @@ SEXP R_subColSummarize_median(SEXP RMatrix, SEXP R_rowIndexList){ |
1329 | 1380 |
} |
1330 | 1381 |
threads = (pthread_t *) Calloc(num_threads, pthread_t); |
1331 | 1382 |
|
1332 |
- /* Initialize and set thread detached attribute */ |
|
1333 |
- pthread_attr_init(&attr); |
|
1383 |
+ /* Set thread detached attribute */ |
|
1334 | 1384 |
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); |
1335 | 1385 |
pthread_attr_setstacksize (&attr, stacksize); |
1336 | 1386 |
|
... | ... |
@@ -1475,11 +1525,17 @@ SEXP R_subColSummarize_medianpolish_log(SEXP RMatrix, SEXP R_rowIndexList){ |
1475 | 1525 |
double chunk_size_d, chunk_tot_d; |
1476 | 1526 |
char *nthreads; |
1477 | 1527 |
pthread_attr_t attr; |
1528 |
+ /* Initialize thread attribute */ |
|
1529 |
+ pthread_attr_init(&attr); |
|
1478 | 1530 |
pthread_t *threads; |
1479 | 1531 |
struct loop_data *args; |
1480 | 1532 |
void *status; |
1481 | 1533 |
#ifdef PTHREAD_STACK_MIN |
1482 |
- size_t stacksize = PTHREAD_STACK_MIN + 0x4000; |
|
1534 |
+#ifdef INFER_MIN_STACKSIZE |
|
1535 |
+ size_t stacksize = __pthread_get_minstack(&attr) + sysconf(_SC_PAGE_SIZE); |
|
1536 |
+#else |
|
1537 |
+ size_t stacksize = PTHREAD_STACK_MIN + sysconf(_SC_PAGE_SIZE); |
|
1538 |
+#endif |
|
1483 | 1539 |
#else |
1484 | 1540 |
size_t stacksize = 0x8000; |
1485 | 1541 |
#endif |
... | ... |
@@ -1507,8 +1563,7 @@ SEXP R_subColSummarize_medianpolish_log(SEXP RMatrix, SEXP R_rowIndexList){ |
1507 | 1563 |
} |
1508 | 1564 |
threads = (pthread_t *) Calloc(num_threads, pthread_t); |
1509 | 1565 |
|
1510 |
- /* Initialize and set thread detached attribute */ |
|
1511 |
- pthread_attr_init(&attr); |
|
1566 |
+ /* Set thread detached attribute */ |
|
1512 | 1567 |
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); |
1513 | 1568 |
pthread_attr_setstacksize (&attr, stacksize); |
1514 | 1569 |
|
... | ... |
@@ -1650,11 +1705,17 @@ SEXP R_subColSummarize_medianpolish(SEXP RMatrix, SEXP R_rowIndexList){ |
1650 | 1705 |
double chunk_size_d, chunk_tot_d; |
1651 | 1706 |
char *nthreads; |
1652 | 1707 |
pthread_attr_t attr; |
1708 |
+ /* Initialize thread attribute */ |
|
1709 |
+ pthread_attr_init(&attr); |
|
1653 | 1710 |
pthread_t *threads; |
1654 | 1711 |
struct loop_data *args; |
1655 | 1712 |
void *status; |
1656 | 1713 |
#ifdef PTHREAD_STACK_MIN |
1657 |
- size_t stacksize = PTHREAD_STACK_MIN + 0x4000; |
|
1714 |
+#ifdef INFER_MIN_STACKSIZE |
|
1715 |
+ size_t stacksize = __pthread_get_minstack(&attr) + sysconf(_SC_PAGE_SIZE); |
|
1716 |
+#else |
|
1717 |
+ size_t stacksize = PTHREAD_STACK_MIN + sysconf(_SC_PAGE_SIZE); |
|
1718 |
+#endif |
|
1658 | 1719 |
#else |
1659 | 1720 |
size_t stacksize = 0x8000; |
1660 | 1721 |
#endif |
... | ... |
@@ -1678,8 +1739,7 @@ SEXP R_subColSummarize_medianpolish(SEXP RMatrix, SEXP R_rowIndexList){ |
1678 | 1739 |
} |
1679 | 1740 |
threads = (pthread_t *) Calloc(num_threads, pthread_t); |
1680 | 1741 |
|
1681 |
- /* Initialize and set thread detached attribute */ |
|
1682 |
- pthread_attr_init(&attr); |
|
1742 |
+ /* Set thread detached attribute */ |
|
1683 | 1743 |
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); |
1684 | 1744 |
pthread_attr_setstacksize (&attr, stacksize); |
1685 | 1745 |
|
... | ... |
@@ -51,6 +51,16 @@ struct loop_data{ |
51 | 51 |
int start_row; |
52 | 52 |
int end_row; |
53 | 53 |
}; |
54 |
+ |
|
55 |
+#ifdef __linux__ |
|
56 |
+#include <features.h> |
|
57 |
+#ifdef __GLIBC__ |
|
58 |
+#ifdef __GLIBC_PREREQ && __GLIBC_PREREQ(2, 15) |
|
59 |
+#define INFER_MIN_STACKSIZE 1 |
|
60 |
+#endif |
|
61 |
+#endif |
|
62 |
+#endif |
|
63 |
+ |
|
54 | 64 |
#endif |
55 | 65 |
|
56 | 66 |
|
... | ... |
@@ -165,11 +175,17 @@ SEXP R_sub_rcModelSummarize_medianpolish(SEXP RMatrix, SEXP R_rowIndexList){ |
165 | 175 |
double chunk_size_d, chunk_tot_d; |
166 | 176 |
char *nthreads; |
167 | 177 |
pthread_attr_t attr; |
178 |
+ /* Initialize thread attribute */ |
|
179 |
+ pthread_attr_init(&attr); |
|
168 | 180 |
pthread_t *threads; |
169 | 181 |
struct loop_data *args; |
170 | 182 |
void *status; |
171 | 183 |
#ifdef PTHREAD_STACK_MIN |
172 |
- size_t stacksize = PTHREAD_STACK_MIN + 0x4000; |
|
184 |
+#ifdef INFER_MIN_STACKSIZE |
|
185 |
+ size_t stacksize = __pthread_get_minstack(&attr) + sysconf(_SC_PAGE_SIZE); |
|
186 |
+#else |
|
187 |
+ size_t stacksize = PTHREAD_STACK_MIN + sysconf(_SC_PAGE_SIZE); |
|
188 |
+#endif |
|
173 | 189 |
#else |
174 | 190 |
size_t stacksize = 0x8000; |
175 | 191 |
#endif |
... | ... |
@@ -211,8 +227,7 @@ SEXP R_sub_rcModelSummarize_medianpolish(SEXP RMatrix, SEXP R_rowIndexList){ |
211 | 227 |
} |
212 | 228 |
threads = (pthread_t *) Calloc(num_threads, pthread_t); |
213 | 229 |
|
214 |
- /* Initialize and set thread detached attribute */ |
|
215 |
- pthread_attr_init(&attr); |
|
230 |
+ /* Set thread detached attribute */ |
|
216 | 231 |
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); |
217 | 232 |
pthread_attr_setstacksize (&attr, stacksize); |
218 | 233 |
|
... | ... |
@@ -480,11 +495,17 @@ SEXP R_sub_rcModelSummarize_plm(SEXP RMatrix, SEXP R_rowIndexList, SEXP PsiCode, |
480 | 495 |
double chunk_size_d, chunk_tot_d; |
481 | 496 |
char *nthreads; |
482 | 497 |
pthread_attr_t attr; |
498 |
+ /* Initialize thread attribute */ |
|
499 |
+ pthread_attr_init(&attr); |
|
483 | 500 |
pthread_t *threads; |
484 | 501 |
struct loop_data *args; |
485 | 502 |
void *status; |
486 | 503 |
#ifdef PTHREAD_STACK_MIN |
487 |
- size_t stacksize = PTHREAD_STACK_MIN + 0x4000; |
|
504 |
+#ifdef INFER_MIN_STACKSIZE |
|
505 |
+ size_t stacksize = __pthread_get_minstack(&attr) + sysconf(_SC_PAGE_SIZE); |
|
506 |
+#else |
|
507 |
+ size_t stacksize = PTHREAD_STACK_MIN + sysconf(_SC_PAGE_SIZE); |
|
508 |
+#endif |
|
488 | 509 |
#else |
489 | 510 |
size_t stacksize = 0x8000; |
490 | 511 |
#endif |
... | ... |
@@ -532,8 +553,7 @@ SEXP R_sub_rcModelSummarize_plm(SEXP RMatrix, SEXP R_rowIndexList, SEXP PsiCode, |
532 | 553 |
} |
533 | 554 |
threads = (pthread_t *) Calloc(num_threads, pthread_t); |
534 | 555 |
|
535 |
- /* Initialize and set thread detached attribute */ |
|
536 |
- pthread_attr_init(&attr); |
|
556 |
+ /* Set thread detached attribute */ |
|
537 | 557 |
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); |
538 | 558 |
pthread_attr_setstacksize (&attr, stacksize); |
539 | 559 |
|
... | ... |
@@ -110,6 +110,16 @@ struct loop_data{ |
110 | 110 |
int start_col; |
111 | 111 |
int end_col; |
112 | 112 |
}; |
113 |
+ |
|
114 |
+#ifdef __linux__ |
|
115 |
+#include <features.h> |
|
116 |
+#ifdef __GLIBC__ |
|
117 |
+#ifdef __GLIBC_PREREQ && __GLIBC_PREREQ(2, 15) |
|
118 |
+#define INFER_MIN_STACKSIZE 1 |
|
119 |
+#endif |
|
120 |
+#endif |
|
121 |
+#endif |
|
122 |
+ |
|
113 | 123 |
#endif |
114 | 124 |
|
115 | 125 |
/***************************************************************************************************** |
... | ... |
@@ -486,11 +496,17 @@ int qnorm_c_l(double *data, size_t rows, size_t cols){ |
486 | 496 |
double chunk_size_d, chunk_tot_d; |
487 | 497 |
char *nthreads; |
488 | 498 |
pthread_attr_t attr; |
499 |
+ /* Initialize thread attribute */ |
|
500 |
+ pthread_attr_init(&attr); |
|
489 | 501 |
pthread_t *threads; |
490 | 502 |
struct loop_data *args; |
491 | 503 |
void *status; |
492 | 504 |
#ifdef PTHREAD_STACK_MIN |
493 |
- size_t stacksize = PTHREAD_STACK_MIN + 0x4000; |
|
505 |
+#ifdef INFER_MIN_STACKSIZE |
|
506 |
+ size_t stacksize = __pthread_get_minstack(&attr); |
|
507 |
+#else |
|
508 |
+ size_t stacksize = PTHREAD_STACK_MIN + sysconf(_SC_PAGE_SIZE); |
|
509 |
+#endif |
|
494 | 510 |
#else |
495 | 511 |
size_t stacksize = 0x8000; |
496 | 512 |
#endif |
... | ... |
@@ -510,8 +526,7 @@ int qnorm_c_l(double *data, size_t rows, size_t cols){ |
510 | 526 |
} |
511 | 527 |
threads = (pthread_t *) Calloc(num_threads, pthread_t); |
512 | 528 |
|
513 |
- /* Initialize and set thread detached attribute */ |
|
514 |
- pthread_attr_init(&attr); |
|
529 |
+ /* Set thread detached attribute */ |
|
515 | 530 |
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); |
516 | 531 |
pthread_attr_setstacksize (&attr, stacksize); |
517 | 532 |
|
... | ... |
@@ -1597,11 +1612,17 @@ int qnorm_c_using_target_l(double *data, size_t rows, size_t cols, double *targe |
1597 | 1612 |
double chunk_size_d, chunk_tot_d; |
1598 | 1613 |
char *nthreads; |
1599 | 1614 |
pthread_attr_t attr; |
1615 |
+ /* Initialize thread attribute */ |
|
1616 |
+ pthread_attr_init(&attr); |
|
1600 | 1617 |
pthread_t *threads; |
1601 | 1618 |
struct loop_data *args; |
1602 | 1619 |
void *status; |
1603 | 1620 |
#ifdef PTHREAD_STACK_MIN |
1604 |
- size_t stacksize = PTHREAD_STACK_MIN + 0x4000; |
|
1621 |
+#ifdef INFER_MIN_STACKSIZE |
|
1622 |
+ size_t stacksize = __pthread_get_minstack(&attr) + sysconf(_SC_PAGE_SIZE); |
|
1623 |
+#else |
|
1624 |
+ size_t stacksize = PTHREAD_STACK_MIN + sysconf(_SC_PAGE_SIZE); |
|
1625 |
+#endif |
|
1605 | 1626 |
#else |
1606 | 1627 |
size_t stacksize = 0x8000; |
1607 | 1628 |
#endif |
... | ... |
@@ -1631,9 +1652,7 @@ int qnorm_c_using_target_l(double *data, size_t rows, size_t cols, double *targe |
1631 | 1652 |
} |
1632 | 1653 |
threads = (pthread_t *) Calloc(num_threads, pthread_t); |
1633 | 1654 |
|
1634 |
- /* Initialize and set thread detached attribute */ |
|
1635 |
- |
|
1636 |
- pthread_attr_init(&attr); |
|
1655 |
+ /* Set thread detached attribute */ |
|
1637 | 1656 |
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); |
1638 | 1657 |
pthread_attr_setstacksize (&attr, stacksize); |
1639 | 1658 |
|
... | ... |
@@ -1890,11 +1909,17 @@ int qnorm_c_determine_target_l(double *data, size_t rows, size_t cols, double *t |
1890 | 1909 |
double chunk_size_d, chunk_tot_d; |
1891 | 1910 |
char *nthreads; |
1892 | 1911 |
pthread_attr_t attr; |
1912 |
+ /* Initialize thread attribute */ |
|
1913 |
+ pthread_attr_init(&attr); |
|
1893 | 1914 |
pthread_t *threads; |
1894 | 1915 |
struct loop_data *args; |
1895 | 1916 |
void *status; |
1896 | 1917 |
#ifdef PTHREAD_STACK_MIN |
1897 |
- size_t stacksize = PTHREAD_STACK_MIN + 0x4000; |
|
1918 |
+#ifdef INFER_MIN_STACKSIZE |
|
1919 |
+ size_t stacksize = __pthread_get_minstack(&attr) + sysconf(_SC_PAGE_SIZE); |
|
1920 |
+#else |
|
1921 |
+ size_t stacksize = PTHREAD_STACK_MIN + sysconf(_SC_PAGE_SIZE); |
|
1922 |
+#endif |
|
1898 | 1923 |
#else |
1899 | 1924 |
size_t stacksize = 0x8000; |
1900 | 1925 |
#endif |
... | ... |
@@ -1910,8 +1935,7 @@ int qnorm_c_determine_target_l(double *data, size_t rows, size_t cols, double *t |
1910 | 1935 |
} |
1911 | 1936 |
threads = (pthread_t *) Calloc(num_threads, pthread_t); |
1912 | 1937 |
|
1913 |
- /* Initialize and set thread detached attribute */ |
|
1914 |
- pthread_attr_init(&attr); |
|
1938 |
+ /* Set thread detached attribute */ |
|
1915 | 1939 |
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); |
1916 | 1940 |
pthread_attr_setstacksize (&attr, stacksize); |
1917 | 1941 |
|
... | ... |
@@ -2484,11 +2508,17 @@ int qnorm_c_determine_target_via_subset_l(double *data, size_t rows, size_t cols |
2484 | 2508 |
double chunk_size_d, chunk_tot_d; |
2485 | 2509 |
char *nthreads; |
2486 | 2510 |
pthread_attr_t attr; |
2511 |
+ /* Initialize thread attribute */ |
|
2512 |
+ pthread_attr_init(&attr); |
|
2487 | 2513 |
pthread_t *threads; |
2488 | 2514 |
struct loop_data *args; |
2489 | 2515 |
void *status; |
2490 | 2516 |
#ifdef PTHREAD_STACK_MIN |
2491 |
- size_t stacksize = PTHREAD_STACK_MIN + 0x4000; |
|
2517 |
+#ifdef INFER_MIN_STACKSIZE |
|
2518 |
+ size_t stacksize = __pthread_get_minstack(&attr) + sysconf(_SC_PAGE_SIZE); |
|
2519 |
+#else |
|
2520 |
+ size_t stacksize = PTHREAD_STACK_MIN + sysconf(_SC_PAGE_SIZE); |
|
2521 |
+#endif |
|
2492 | 2522 |
#else |
2493 | 2523 |
size_t stacksize = 0x8000; |
2494 | 2524 |
#endif |
... | ... |
@@ -2504,8 +2534,7 @@ int qnorm_c_determine_target_via_subset_l(double *data, size_t rows, size_t cols |
2504 | 2534 |
} |
2505 | 2535 |
threads = (pthread_t *) Calloc(num_threads, pthread_t); |
2506 | 2536 |
|
2507 |
- /* Initialize and set thread detached attribute */ |
|
2508 |
- pthread_attr_init(&attr); |
|
2537 |
+ /* Set thread detached attribute */ |
|
2509 | 2538 |
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); |
2510 | 2539 |
pthread_attr_setstacksize (&attr, stacksize); |
2511 | 2540 |
|
... | ... |
@@ -2988,11 +3017,17 @@ int qnorm_c_using_target_via_subset_l(double *data, size_t rows, size_t cols, in |
2988 | 3017 |
double chunk_size_d, chunk_tot_d; |
2989 | 3018 |
char *nthreads; |
2990 | 3019 |
pthread_attr_t attr; |
3020 |
+ /* Initialize thread attribute */ |
|
3021 |
+ pthread_attr_init(&attr); |
|
2991 | 3022 |
pthread_t *threads; |
2992 | 3023 |
struct loop_data *args; |
2993 | 3024 |
void *status; |
2994 | 3025 |
#ifdef PTHREAD_STACK_MIN |
2995 |
- size_t stacksize = PTHREAD_STACK_MIN + 0x4000; |
|
3026 |
+#ifdef INFER_MIN_STACKSIZE |
|
3027 |
+ size_t stacksize = __pthread_get_minstack(&attr) + sysconf(_SC_PAGE_SIZE); |
|
3028 |
+#else |
|
3029 |
+ size_t stacksize = PTHREAD_STACK_MIN + sysconf(_SC_PAGE_SIZE); |
|
3030 |
+#endif |
|
2996 | 3031 |
#else |
2997 | 3032 |
size_t stacksize = 0x8000; |
2998 | 3033 |
#endif |
... | ... |
@@ -3022,9 +3057,7 @@ int qnorm_c_using_target_via_subset_l(double *data, size_t rows, size_t cols, in |
3022 | 3057 |
} |
3023 | 3058 |
threads = (pthread_t *) Calloc(num_threads, pthread_t); |
3024 | 3059 |
|
3025 |
- /* Initialize and set thread detached attribute */ |
|
3026 |
- |
|
3027 |
- pthread_attr_init(&attr); |
|
3060 |
+ /* Set thread detached attribute */ |
|
3028 | 3061 |
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); |
3029 | 3062 |
pthread_attr_setstacksize (&attr, stacksize); |
3030 | 3063 |
|
... | ... |
@@ -58,6 +58,16 @@ struct loop_data{ |
58 | 58 |
size_t start_col; |
59 | 59 |
size_t end_col; |
60 | 60 |
}; |
61 |
+ |
|
62 |
+#ifdef __linux__ |
|
63 |
+#include <features.h> |
|
64 |
+#ifdef __GLIBC__ |
|
65 |
+#ifdef __GLIBC_PREREQ && __GLIBC_PREREQ(2, 15) |
|
66 |
+#define INFER_MIN_STACKSIZE 1 |
|
67 |
+#endif |
|
68 |
+#endif |
|
69 |
+#endif |
|
70 |
+ |
|
61 | 71 |
#endif |
62 | 72 |
|
63 | 73 |
|
... | ... |
@@ -347,11 +357,17 @@ void rma_bg_correct(double *PM, size_t rows, size_t cols){ |
347 | 357 |
double chunk_size_d, chunk_tot_d; |
348 | 358 |
char *nthreads; |
349 | 359 |
pthread_attr_t attr; |
360 |
+ /* Initialize thread attribute */ |
|
361 |
+ pthread_attr_init(&attr); |
|
350 | 362 |
pthread_t *threads; |
351 | 363 |
struct loop_data *args; |
352 | 364 |
void *status; |
353 | 365 |
#ifdef PTHREAD_STACK_MIN |
354 |
- size_t stacksize = PTHREAD_STACK_MIN + 0x4000; |
|
366 |
+#ifdef INFER_MIN_STACKSIZE |
|
367 |
+ size_t stacksize = __pthread_get_minstack(&attr) + sysconf(_SC_PAGE_SIZE); |
|
368 |
+#else |
|
369 |
+ size_t stacksize = PTHREAD_STACK_MIN + sysconf(_SC_PAGE_SIZE); |
|
370 |
+#endif |
|
355 | 371 |
#else |
356 | 372 |
size_t stacksize = 0x8000; |
357 | 373 |
#endif |
... | ... |
@@ -369,8 +385,7 @@ void rma_bg_correct(double *PM, size_t rows, size_t cols){ |
369 | 385 |
} |
370 | 386 |
threads = (pthread_t *) Calloc(num_threads, pthread_t); |
371 | 387 |
|
372 |
- /* Initialize and set thread detached attribute */ |
|
373 |
- pthread_attr_init(&attr); |
|
388 |
+ /* Set thread detached attribute */ |
|
374 | 389 |
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); |
375 | 390 |
pthread_attr_setstacksize (&attr, stacksize); |
376 | 391 |
/* this code works out how many threads to use and allocates ranges of columns to each thread */ |