Line data Source code
1 : /* 2 : * Copyright (C) 2013 Andrea Mazzoleni 3 : * 4 : * This program is free software: you can redistribute it and/or modify 5 : * it under the terms of the GNU General Public License as published by 6 : * the Free Software Foundation, either version 2 of the License, or 7 : * (at your option) any later version. 8 : * 9 : * This program is distributed in the hope that it will be useful, 10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 : * GNU General Public License for more details. 13 : */ 14 : 15 : #include "internal.h" 16 : #include "memory.h" 17 : 18 12686 : void *raid_malloc_align(size_t size, size_t align_size, void **freeptr) 19 : { 20 : unsigned char *ptr; 21 : uintptr_t offset; 22 : 23 12686 : ptr = malloc(size + align_size); 24 12686 : if (!ptr) { 25 : /* LCOV_EXCL_START */ 26 : return 0; 27 : /* LCOV_EXCL_STOP */ 28 : } 29 : 30 12686 : *freeptr = ptr; 31 : 32 12686 : offset = ((uintptr_t)ptr) % align_size; 33 : 34 12686 : if (offset != 0) 35 11944 : ptr += align_size - offset; 36 : 37 12686 : return ptr; 38 : } 39 : 40 179 : void *raid_malloc(size_t size, void **freeptr) 41 : { 42 179 : return raid_malloc_align(size, RAID_MALLOC_ALIGN, freeptr); 43 : } 44 : 45 12500 : void **raid_malloc_vector_align(int nd, int n, size_t size, size_t align_size, size_t displacement_size, void **freeptr) 46 : { 47 : void **v; 48 : unsigned char *va; 49 : int i; 50 : 51 12500 : BUG_ON(n <= 0 || nd < 0); 52 : 53 12500 : v = malloc(n * sizeof(void *)); 54 12500 : if (!v) { 55 : /* LCOV_EXCL_START */ 56 : return 0; 57 : /* LCOV_EXCL_STOP */ 58 : } 59 : 60 12500 : va = raid_malloc_align(n * (size + displacement_size), align_size, freeptr); 61 12500 : if (!va) { 62 : /* LCOV_EXCL_START */ 63 : free(v); 64 : return 0; 65 : /* LCOV_EXCL_STOP */ 66 : } 67 : 68 169367 : for (i = 0; i < n; ++i) { 69 156867 : v[i] = va; 70 156867 : va += size + displacement_size; 71 : } 72 : 73 : /* reverse order of the data blocks */ 74 : /* because they are usually accessed from the last one */ 75 50038 : for (i = 0; i < nd / 2; ++i) { 76 37538 : void *ptr = v[i]; 77 : 78 37538 : v[i] = v[nd - 1 - i]; 79 37538 : v[nd - 1 - i] = ptr; 80 : } 81 : 82 12500 : return v; 83 : } 84 : 85 12500 : void **raid_malloc_vector(int nd, int n, size_t size, void **freeptr) 86 : { 87 12500 : return raid_malloc_vector_align(nd, n, size, RAID_MALLOC_ALIGN, RAID_MALLOC_DISPLACEMENT, freeptr); 88 : } 89 : 90 5 : void raid_mrand_vector(unsigned seed, int n, size_t size, void **vv) 91 : { 92 5 : unsigned char **v = (unsigned char **)vv; 93 : int i; 94 : size_t j; 95 : 96 124 : for (i = 0; i < n; ++i) 97 30583 : for (j = 0; j < size; ++j) { 98 : /* basic C99/C11 linear congruential generator */ 99 30464 : seed = seed * 1103515245U + 12345U; 100 : 101 30464 : v[i][j] = seed >> 16; 102 : } 103 5 : } 104 : 105 3 : int raid_mtest_vector(int n, size_t size, void **vv) 106 : { 107 3 : unsigned char **v = (unsigned char **)vv; 108 : int i; 109 : size_t j; 110 : unsigned k; 111 : unsigned char d; 112 : unsigned char p; 113 : 114 : /* fill with 0 */ 115 3 : d = 0; 116 98 : for (i = 0; i < n; ++i) 117 24415 : for (j = 0; j < size; ++j) 118 24320 : v[i][j] = d; 119 : 120 : /* test with all the byte patterns */ 121 768 : for (k = 1; k < 256; ++k) { 122 765 : p = d; 123 765 : d = k; 124 : 125 : /* forward fill */ 126 24990 : for (i = 0; i < n; ++i) { 127 6225825 : for (j = 0; j < size; ++j) { 128 6201600 : if (v[i][j] != p) { 129 : /* LCOV_EXCL_START */ 130 : return -1; 131 : /* LCOV_EXCL_STOP */ 132 : } 133 6201600 : v[i][j] = d; 134 : } 135 : } 136 : 137 765 : p = d; 138 765 : d = ~p; 139 : /* backward fill with complement */ 140 24990 : for (i = 0; i < n; ++i) { 141 6225825 : for (j = size; j > 0; --j) { 142 6201600 : if (v[i][j - 1] != p) { 143 : /* LCOV_EXCL_START */ 144 : return -1; 145 : /* LCOV_EXCL_STOP */ 146 : } 147 6201600 : v[i][j - 1] = d; 148 : } 149 : } 150 : } 151 : 152 3 : return 0; 153 : } 154 :