| 102 | } |
| 103 | |
| 104 | static void _hpt_realloc(unsigned int frag_overhead) |
| 105 | { |
| 106 | struct hpt_frag *f, *ret; |
| 107 | ssize_t size; |
| 108 | |
| 109 | if (list_empty(&hpt_frags)) |
| 110 | return _hpt_malloc(frag_overhead); |
| 111 | |
| 112 | f = list_entry(hpt_frags.prev, struct hpt_frag, list); |
| 113 | list_del(&f->list); |
| 114 | |
| 115 | hpt_my_used -= f->size; |
| 116 | |
| 117 | if (should_grow) { |
| 118 | if (!check_limit() || f->size >= MY_MAX_USED) { |
| 119 | should_grow = 0; |
| 120 | goto out; |
| 121 | } |
| 122 | |
| 123 | size = f->size + (rand() % HPT_FAC) * (HPT_MAX_ALLOC_SZ/HPT_FAC) + 1; |
| 124 | } else { |
| 125 | size = rand() % f->size + 1; |
| 126 | } |
| 127 | |
| 128 | ret = REALLOC(f, sizeof *ret + size); |
| 129 | if (!ret) { |
| 130 | LM_ERR("oom\n"); |
| 131 | should_grow = 0; |
| 132 | goto out; |
| 133 | } |
| 134 | memset(ret, -1, sizeof *ret + size); |
| 135 | |
| 136 | if ((unsigned long)ret % MEM_ALIGN == 0) |
| 137 | aligned_reallocs++; |
| 138 | |
| 139 | ret->chunk = (void *)(ret + 1); |
| 140 | ret->size = size; |
| 141 | hpt_my_used += size; |
| 142 | |
| 143 | list_add(&ret->list, &hpt_frags); |
| 144 | |
| 145 | reallocs++; |
| 146 | return; |
| 147 | |
| 148 | out: |
| 149 | FREE(f); |
| 150 | frees++; |
| 151 | fragments--; |
| 152 | } |
| 153 | |
| 154 | #define hpt_malloc(frag_overhead) (rand() & 1 ? \ |
| 155 | _hpt_malloc(frag_overhead) : _hpt_realloc(frag_overhead)) |
nothing calls this directly
no test coverage detected