From 00416c76d19863732881ca0a4aae90f651b4bc5d Mon Sep 17 00:00:00 2001 From: Heng Li Date: Sat, 2 Sep 2017 18:23:29 -0400 Subject: [PATCH 1/8] for MinGW32 compatibility get rid of alloca() --- getopt.c | 4 ++++ kthread.c | 9 ++++----- sketch.c | 8 ++------ 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/getopt.c b/getopt.c index ca2d79d..7139bfd 100644 --- a/getopt.c +++ b/getopt.c @@ -11,12 +11,16 @@ int optind=1, opterr=1, optopt, __optpos, optreset=0; static void __getopt_msg(const char *a, const char *b, const char *c, size_t l) { FILE *f = stderr; +#if !defined(WIN32) && !defined(_WIN32) flockfile(f); +#endif fputs(a, f); fwrite(b, strlen(b), 1, f); fwrite(c, 1, l, f); fputc('\n', f); +#if !defined(WIN32) && !defined(_WIN32) funlockfile(f); +#endif } int getopt(int argc, char * const argv[], const char *optstring) diff --git a/kthread.c b/kthread.c index 6004435..04909c8 100644 --- a/kthread.c +++ b/kthread.c @@ -3,9 +3,7 @@ #include #include -#if defined(WIN32) || defined(_WIN32) -#include -#define alloca _alloca +#if (defined(WIN32) || defined(_WIN32)) && defined(_MSC_VER) #define __sync_fetch_and_add(ptr, addend) _InterlockedExchangeAdd((void*)ptr, addend) #endif @@ -59,12 +57,13 @@ void kt_for(int n_threads, void (*func)(void*,long,int), void *data, long n) kt_for_t t; pthread_t *tid; t.func = func, t.data = data, t.n_threads = n_threads, t.n = n; - t.w = (ktf_worker_t*)alloca(n_threads * sizeof(ktf_worker_t)); - tid = (pthread_t*)alloca(n_threads * sizeof(pthread_t)); + t.w = (ktf_worker_t*)calloc(n_threads, sizeof(ktf_worker_t)); + tid = (pthread_t*)calloc(n_threads, sizeof(pthread_t)); for (i = 0; i < n_threads; ++i) t.w[i].t = &t, t.w[i].i = i; for (i = 0; i < n_threads; ++i) pthread_create(&tid[i], 0, ktf_worker, &t.w[i]); for (i = 0; i < n_threads; ++i) pthread_join(tid[i], 0); + free(tid); free(t.w); } else { long j; for (j = 0; j < n; ++j) func(data, j, 0); diff --git a/sketch.c b/sketch.c index ab3bcc8..9bc5eba 100644 --- a/sketch.c +++ b/sketch.c @@ -5,11 +5,6 @@ #include "kvec.h" #include "minimap.h" -#if defined(WIN32) || defined(_WIN32) -#include -#define alloca _alloca -#endif - unsigned char seq_nt4_table[256] = { 0, 1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, @@ -86,7 +81,7 @@ void mm_sketch(void *km, const char *str, int len, int w, int k, uint32_t rid, i tiny_queue_t tq; assert(len > 0 && w > 0 && k > 0 && k <= 28); // 56 bits for k-mer; could use long k-mers, but 28 enough in practice - buf = (mm128_t*)alloca(w * 16); + buf = (mm128_t*)calloc(w, 16); memset(buf, 0xff, w * 16); memset(&tq, 0, sizeof(tiny_queue_t)); kv_resize(mm128_t, km, *p, p->n + len/w); @@ -145,4 +140,5 @@ void mm_sketch(void *km, const char *str, int len, int w, int k, uint32_t rid, i } if (min.x != UINT64_MAX) kv_push(mm128_t, km, *p, min); + free(buf); } From 3d48516885b0770e341edbc4454c03e6cbc3392f Mon Sep 17 00:00:00 2001 From: Heng Li Date: Sat, 2 Sep 2017 18:32:45 -0400 Subject: [PATCH 2/8] reduced a heap allocation which *might* be frequent for short reads --- sketch.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sketch.c b/sketch.c index 9bc5eba..db359eb 100644 --- a/sketch.c +++ b/sketch.c @@ -77,11 +77,10 @@ void mm_sketch(void *km, const char *str, int len, int w, int k, uint32_t rid, i { uint64_t shift1 = 2 * (k - 1), mask = (1ULL<<2*k) - 1, kmer[2] = {0,0}; int i, j, l, buf_pos, min_pos, kmer_span = 0; - mm128_t *buf, min = { UINT64_MAX, UINT64_MAX }; + mm128_t buf[256], min = { UINT64_MAX, UINT64_MAX }; tiny_queue_t tq; - assert(len > 0 && w > 0 && k > 0 && k <= 28); // 56 bits for k-mer; could use long k-mers, but 28 enough in practice - buf = (mm128_t*)calloc(w, 16); + assert(len > 0 && (w > 0 && w < 256) && (k > 0 && k <= 28)); // 56 bits for k-mer; could use long k-mers, but 28 enough in practice memset(buf, 0xff, w * 16); memset(&tq, 0, sizeof(tiny_queue_t)); kv_resize(mm128_t, km, *p, p->n + len/w); @@ -140,5 +139,4 @@ void mm_sketch(void *km, const char *str, int len, int w, int k, uint32_t rid, i } if (min.x != UINT64_MAX) kv_push(mm128_t, km, *p, min); - free(buf); } From 2a5d5b6f12575ff57642943ed2bee931fa759887 Mon Sep 17 00:00:00 2001 From: Heng Li Date: Sat, 2 Sep 2017 18:37:48 -0400 Subject: [PATCH 3/8] print size_t with %zu instead of %lu --- kalloc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kalloc.c b/kalloc.c index 9356d40..2e6dbb1 100644 --- a/kalloc.c +++ b/kalloc.c @@ -46,7 +46,7 @@ static size_t *morecore(kmem_t *km, size_t nu) up = (size_t*)malloc(rnu * sizeof(size_t)); if (!up) { /* fail to allocate memory */ km_stat(km); - fprintf(stderr, "[morecore] %lu bytes requested but not available.\n", rnu * sizeof(size_t)); + fprintf(stderr, "[morecore] %zu bytes requested but not available.\n", rnu * sizeof(size_t)); exit(1); } /* put the pointer in km->list_head */ @@ -209,6 +209,6 @@ void km_stat(const void *_km) --n_blocks; frag = 1.0/1024.0 * n_units * sizeof(size_t) / n_blocks; - fprintf(stderr, "[kr_stat] tot=%lu, free=%lu, n_block=%u, max_block=%lu, frag_len=%.3fK\n", + fprintf(stderr, "[kr_stat] tot=%zu, free=%zu, n_block=%u, max_block=%zu, frag_len=%.3fK\n", km->total_allocated, n_units * sizeof(size_t), n_blocks, max_block * sizeof(size_t), frag); } From 6f4cbf4f1263807eb2af0734d138a1db87aae8cc Mon Sep 17 00:00:00 2001 From: Heng Li Date: Sat, 2 Sep 2017 18:48:14 -0400 Subject: [PATCH 4/8] ok, %zu is a C99 feature... --- kalloc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kalloc.c b/kalloc.c index 2e6dbb1..fa9bc88 100644 --- a/kalloc.c +++ b/kalloc.c @@ -46,7 +46,7 @@ static size_t *morecore(kmem_t *km, size_t nu) up = (size_t*)malloc(rnu * sizeof(size_t)); if (!up) { /* fail to allocate memory */ km_stat(km); - fprintf(stderr, "[morecore] %zu bytes requested but not available.\n", rnu * sizeof(size_t)); + fprintf(stderr, "[morecore] %lu bytes requested but not available.\n", (unsigned long)rnu * sizeof(size_t)); exit(1); } /* put the pointer in km->list_head */ @@ -209,6 +209,6 @@ void km_stat(const void *_km) --n_blocks; frag = 1.0/1024.0 * n_units * sizeof(size_t) / n_blocks; - fprintf(stderr, "[kr_stat] tot=%zu, free=%zu, n_block=%u, max_block=%zu, frag_len=%.3fK\n", - km->total_allocated, n_units * sizeof(size_t), n_blocks, max_block * sizeof(size_t), frag); + fprintf(stderr, "[kr_stat] tot=%lu, free=%lu, n_block=%u, max_block=%lu, frag_len=%.3fK\n", + (unsigned long)km->total_allocated, (unsigned long)n_units * sizeof(size_t), n_blocks, (unsigned long)max_block * sizeof(size_t), frag); } From 3d3fde82246d6b6c846f86cafefdcfafc6d4467b Mon Sep 17 00:00:00 2001 From: Heng Li Date: Sat, 2 Sep 2017 18:50:42 -0400 Subject: [PATCH 5/8] replaced remaining alloca() --- kthread.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/kthread.c b/kthread.c index 04909c8..249ceea 100644 --- a/kthread.c +++ b/kthread.c @@ -141,16 +141,17 @@ void kt_pipeline(int n_threads, void *(*func)(void*, int, void*), void *shared_d pthread_mutex_init(&aux.mutex, 0); pthread_cond_init(&aux.cv, 0); - aux.workers = (ktp_worker_t*)alloca(n_threads * sizeof(ktp_worker_t)); + aux.workers = (ktp_worker_t*)calloc(n_threads, sizeof(ktp_worker_t)); for (i = 0; i < n_threads; ++i) { ktp_worker_t *w = &aux.workers[i]; w->step = 0; w->pl = &aux; w->data = 0; w->index = aux.index++; } - tid = (pthread_t*)alloca(n_threads * sizeof(pthread_t)); + tid = (pthread_t*)calloc(n_threads, sizeof(pthread_t)); for (i = 0; i < n_threads; ++i) pthread_create(&tid[i], 0, ktp_worker, &aux.workers[i]); for (i = 0; i < n_threads; ++i) pthread_join(tid[i], 0); + free(tid); free(aux.workers); pthread_mutex_destroy(&aux.mutex); pthread_cond_destroy(&aux.cv); From aeb6b5eeb1a30f17db868202fffc9ea7b385f565 Mon Sep 17 00:00:00 2001 From: Heng Li Date: Sat, 2 Sep 2017 19:29:52 -0400 Subject: [PATCH 6/8] fixed an issue due to the 64-bit assumption --- kdq.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kdq.h b/kdq.h index 4a67c0b..8ae5c97 100644 --- a/kdq.h +++ b/kdq.h @@ -3,11 +3,12 @@ #include #include +#include #include "kalloc.h" #define __KDQ_TYPE(type) \ typedef struct { \ - size_t front:58, bits:6, count, mask; \ + uint64_t front:58, bits:6, count, mask; \ type *a; \ void *km; \ } kdq_##type##_t; From 33423e156883e81ec0b0418f2f1658f447dc45d3 Mon Sep 17 00:00:00 2001 From: Heng Li Date: Sat, 2 Sep 2017 21:05:03 -0400 Subject: [PATCH 7/8] get rid of the last var-sized array in ksort for MSVC --- ksort.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ksort.h b/ksort.h index 1f2a3dd..899ebd2 100644 --- a/ksort.h +++ b/ksort.h @@ -30,6 +30,7 @@ #include #include +#include typedef struct { void *left, *right; @@ -78,6 +79,7 @@ typedef const char *ksstr_t; #define KSORT_INIT_STR KSORT_INIT(str, ksstr_t, ks_lt_str) #define RS_MIN_SIZE 64 +#define RS_MAX_BITS 8 #define KRADIX_SORT_INIT(name, rstype_t, rskey, sizeof_key) \ typedef struct { \ @@ -98,7 +100,8 @@ typedef const char *ksstr_t; { \ rstype_t *i; \ int size = 1<b = k->e = beg; \ for (i = beg; i != end; ++i) ++b[rskey(*i)>>s&m].e; \ for (k = b + 1; k != be; ++k) \ @@ -127,7 +130,7 @@ typedef const char *ksstr_t; void radix_sort_##name(rstype_t *beg, rstype_t *end) \ { \ if (end - beg <= RS_MIN_SIZE) rs_insertsort_##name(beg, end); \ - else rs_sort_##name(beg, end, 8, sizeof_key * 8 - 8); \ + else rs_sort_##name(beg, end, RS_MAX_BITS, (sizeof_key - 1) * RS_N_BITS); \ } #endif From f50b9a14a71b6149144151b8a467f9ba0c4f02cd Mon Sep 17 00:00:00 2001 From: Heng Li Date: Sat, 2 Sep 2017 21:07:19 -0400 Subject: [PATCH 8/8] last commit can't be compiled --- ksort.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ksort.h b/ksort.h index 899ebd2..7cd65a5 100644 --- a/ksort.h +++ b/ksort.h @@ -130,7 +130,7 @@ typedef const char *ksstr_t; void radix_sort_##name(rstype_t *beg, rstype_t *end) \ { \ if (end - beg <= RS_MIN_SIZE) rs_insertsort_##name(beg, end); \ - else rs_sort_##name(beg, end, RS_MAX_BITS, (sizeof_key - 1) * RS_N_BITS); \ + else rs_sort_##name(beg, end, RS_MAX_BITS, (sizeof_key - 1) * RS_MAX_BITS); \ } #endif