Browse code

Merge branch 'master' of https://github.com/franciscodavid/preprocessCore into franciscodavid-master

Ben Bolstad authored on 01/02/2020 18:00:13
Showing6 changed files

... ...
@@ -3338,18 +3338,6 @@ if test "x$use_pthread_stack_min" = xno; then
3338 3338
 fi
3339 3339
 
3340 3340
 
3341
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if R is using openblas" >&5
3342
-$as_echo_n "checking if R is using openblas... " >&6; }
3343
-BLAS_LIBS=`"${R_HOME}/bin/R" CMD config BLAS_LIBS`
3344
-if echo "${BLAS_LIBS}" | grep openblas > /dev/null; then
3345
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: openblas found. preprocessCore threading will be disabled" >&5
3346
-$as_echo "openblas found. preprocessCore threading will be disabled" >&6; }
3347
-    use_pthreads=no
3348
-else
3349
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: openblas not found. preprocessCore threading will not be disabled" >&5
3350
-$as_echo "openblas not found. preprocessCore threading will not be disabled" >&6; }
3351
-fi
3352
-
3353 3341
 
3354 3342
 # Check whether --enable-threading was given.
3355 3343
 if test "${enable_threading+set}" = set; then :
... ...
@@ -55,14 +55,6 @@ if test "x$use_pthread_stack_min" = xno; then
55 55
 fi
56 56
 
57 57
 
58
-AC_MSG_CHECKING([if R is using openblas])
59
-BLAS_LIBS=`"${R_HOME}/bin/R" CMD config BLAS_LIBS`
60
-if echo "${BLAS_LIBS}" | grep openblas > /dev/null; then
61
-    AC_MSG_RESULT([openblas found. preprocessCore threading will be disabled])
62
-    use_pthreads=no
63
-else
64
-    AC_MSG_RESULT([openblas not found. preprocessCore threading will not be disabled])
65
-fi
66 58
 
67 59
 
68 60
 AC_ARG_ENABLE([threading],
... ...
@@ -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
   
... ...
@@ -50,6 +50,16 @@ struct loop_data{
50 50
   int start_row;
51 51
   int end_row;
52 52
 };
53
+
54
+#ifdef __linux__
55
+#include <features.h>
56
+#ifdef __GLIBC__
57
+#ifdef __GLIBC_PREREQ && __GLIBC_PREREQ(2, 15)
58
+#define INFER_MIN_STACKSIZE 1
59
+#endif
60
+#endif
61
+#endif
62
+
53 63
 #endif
54 64
 
55 65
 
... ...
@@ -164,11 +174,17 @@ SEXP R_sub_rcModelSummarize_medianpolish(SEXP RMatrix, SEXP R_rowIndexList){
164 174
   double chunk_size_d, chunk_tot_d;
165 175
   char *nthreads;
166 176
   pthread_attr_t attr;
177
+  /* Initialize thread attribute */
178
+  pthread_attr_init(&attr);
167 179
   pthread_t *threads;
168 180
   struct loop_data *args;
169 181
   void *status; 
170 182
 #ifdef PTHREAD_STACK_MIN
171
-  size_t stacksize = PTHREAD_STACK_MIN + 0x4000;
183
+#ifdef INFER_MIN_STACKSIZE
184
+  size_t stacksize = __pthread_get_minstack(&attr) + sysconf(_SC_PAGE_SIZE);
185
+#else
186
+  size_t stacksize = PTHREAD_STACK_MIN + sysconf(_SC_PAGE_SIZE);
187
+#endif
172 188
 #else
173 189
   size_t stacksize = 0x8000;
174 190
 #endif
... ...
@@ -210,8 +226,7 @@ SEXP R_sub_rcModelSummarize_medianpolish(SEXP RMatrix, SEXP R_rowIndexList){
210 226
   }
211 227
   threads = (pthread_t *) Calloc(num_threads, pthread_t);
212 228
 
213
-  /* Initialize and set thread detached attribute */
214
-  pthread_attr_init(&attr);
229
+  /* Set thread detached attribute */
215 230
   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
216 231
   pthread_attr_setstacksize (&attr, stacksize);
217 232
   
... ...
@@ -479,11 +494,17 @@ SEXP R_sub_rcModelSummarize_plm(SEXP RMatrix, SEXP R_rowIndexList, SEXP PsiCode,
479 494
   double chunk_size_d, chunk_tot_d;
480 495
   char *nthreads;
481 496
   pthread_attr_t attr;
497
+  /* Initialize thread attribute */
498
+  pthread_attr_init(&attr);
482 499
   pthread_t *threads;
483 500
   struct loop_data *args;
484 501
   void *status; 
485 502
 #ifdef PTHREAD_STACK_MIN
486
-  size_t stacksize = PTHREAD_STACK_MIN + 0x4000;
503
+#ifdef INFER_MIN_STACKSIZE
504
+  size_t stacksize = __pthread_get_minstack(&attr) + sysconf(_SC_PAGE_SIZE);
505
+#else
506
+  size_t stacksize = PTHREAD_STACK_MIN + sysconf(_SC_PAGE_SIZE);
507
+#endif
487 508
 #else
488 509
   size_t stacksize = 0x8000;
489 510
 #endif
... ...
@@ -531,8 +552,7 @@ SEXP R_sub_rcModelSummarize_plm(SEXP RMatrix, SEXP R_rowIndexList, SEXP PsiCode,
531 552
   }
532 553
   threads = (pthread_t *) Calloc(num_threads, pthread_t);
533 554
 
534
-  /* Initialize and set thread detached attribute */
535
-  pthread_attr_init(&attr);
555
+  /* Set thread detached attribute */
536 556
   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
537 557
   pthread_attr_setstacksize (&attr, stacksize);
538 558
   
... ...
@@ -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 */