Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0-or-later 2 : // Copyright (C) 2013 Andrea Mazzoleni 3 : 4 : #include "internal.h" 5 : #include "memory.h" 6 : 7 14930 : void *raid_malloc_align(size_t size, size_t align_size, void **freeptr) 8 : { 9 : unsigned char *ptr; 10 : uintptr_t offset; 11 : 12 14930 : ptr = malloc(size + align_size); 13 14930 : if (!ptr) { 14 : /* LCOV_EXCL_START */ 15 : return 0; 16 : /* LCOV_EXCL_STOP */ 17 : } 18 : 19 14930 : *freeptr = ptr; 20 : 21 14930 : offset = ((uintptr_t)ptr) % align_size; 22 : 23 14930 : if (offset != 0) 24 14142 : ptr += align_size - offset; 25 : 26 14930 : return ptr; 27 : } 28 : 29 214 : void *raid_malloc(size_t size, void **freeptr) 30 : { 31 214 : return raid_malloc_align(size, RAID_MALLOC_ALIGN, freeptr); 32 : } 33 : 34 14709 : void **raid_malloc_vector_align(int nd, int n, size_t size, size_t align_size, size_t displacement_size, void **freeptr) 35 : { 36 : void **v; 37 : unsigned char *va; 38 : int i; 39 : 40 14709 : BUG_ON(n <= 0 || nd < 0); 41 : 42 14709 : v = malloc(n * sizeof(void *)); 43 14709 : if (!v) { 44 : /* LCOV_EXCL_START */ 45 : return 0; 46 : /* LCOV_EXCL_STOP */ 47 : } 48 : 49 14709 : va = raid_malloc_align(n * (size + displacement_size), align_size, freeptr); 50 14709 : if (!va) { 51 : /* LCOV_EXCL_START */ 52 : free(v); 53 : return 0; 54 : /* LCOV_EXCL_STOP */ 55 : } 56 : 57 188178 : for (i = 0; i < n; ++i) { 58 173469 : v[i] = va; 59 173469 : va += size + displacement_size; 60 : } 61 : 62 : /* 63 : * Reverse order of the data blocks 64 : * because they are usually accessed from the last one 65 : */ 66 56535 : for (i = 0; i < nd / 2; ++i) { 67 41826 : void *ptr = v[i]; 68 : 69 41826 : v[i] = v[nd - 1 - i]; 70 41826 : v[nd - 1 - i] = ptr; 71 : } 72 : 73 14709 : return v; 74 : } 75 : 76 14581 : void **raid_malloc_vector(int nd, int n, size_t size, void **freeptr) 77 : { 78 14581 : return raid_malloc_vector_align(nd, n, size, RAID_MALLOC_ALIGN, RAID_MALLOC_DISPLACEMENT, freeptr); 79 : } 80 : 81 5 : void raid_mrand_vector(unsigned seed, int n, size_t size, void **vv) 82 : { 83 5 : unsigned char **v = (unsigned char **)vv; 84 : int i; 85 : size_t j; 86 : 87 124 : for (i = 0; i < n; ++i) 88 30583 : for (j = 0; j < size; ++j) { 89 : /* basic C99/C11 linear congruential generator */ 90 30464 : seed = seed * 1103515245U + 12345U; 91 : 92 30464 : v[i][j] = seed >> 16; 93 : } 94 5 : } 95 : 96 3 : int raid_mtest_vector(int n, size_t size, void **vv) 97 : { 98 3 : unsigned char **v = (unsigned char **)vv; 99 : int i; 100 : size_t j; 101 : unsigned k; 102 : unsigned char d; 103 : unsigned char p; 104 : 105 : /* fill with 0 */ 106 3 : d = 0; 107 98 : for (i = 0; i < n; ++i) 108 24415 : for (j = 0; j < size; ++j) 109 24320 : v[i][j] = d; 110 : 111 : /* test with all the byte patterns */ 112 768 : for (k = 1; k < 256; ++k) { 113 765 : p = d; 114 765 : d = k; 115 : 116 : /* forward fill */ 117 24990 : for (i = 0; i < n; ++i) { 118 6225825 : for (j = 0; j < size; ++j) { 119 6201600 : if (v[i][j] != p) { 120 : /* LCOV_EXCL_START */ 121 : return -1; 122 : /* LCOV_EXCL_STOP */ 123 : } 124 6201600 : v[i][j] = d; 125 : } 126 : } 127 : 128 765 : p = d; 129 765 : d = ~p; 130 : /* backward fill with complement */ 131 24990 : for (i = 0; i < n; ++i) { 132 6225825 : for (j = size; j > 0; --j) { 133 6201600 : if (v[i][j - 1] != p) { 134 : /* LCOV_EXCL_START */ 135 : return -1; 136 : /* LCOV_EXCL_STOP */ 137 : } 138 6201600 : v[i][j - 1] = d; 139 : } 140 : } 141 : } 142 : 143 3 : return 0; 144 : } 145 :