| 153 | |
| 154 | |
| 155 | void *alloc_root(MEM_ROOT *mem_root, size_t length) |
| 156 | { |
| 157 | #if defined(HAVE_purify) && defined(EXTRA_DEBUG) |
| 158 | reg1 USED_MEM *next; |
| 159 | DBUG_ENTER("alloc_root"); |
| 160 | DBUG_PRINT("enter",("root: 0x%lx", (long) mem_root)); |
| 161 | |
| 162 | DBUG_ASSERT(alloc_root_inited(mem_root)); |
| 163 | |
| 164 | DBUG_EXECUTE_IF("simulate_out_of_memory", |
| 165 | { |
| 166 | if (mem_root->error_handler) |
| 167 | (*mem_root->error_handler)(); |
| 168 | DBUG_SET("-d,simulate_out_of_memory"); |
| 169 | DBUG_RETURN((void*) 0); /* purecov: inspected */ |
| 170 | }); |
| 171 | |
| 172 | length+=ALIGN_SIZE(sizeof(USED_MEM)); |
| 173 | if (!(next = (USED_MEM*) my_malloc(length,MYF(MY_WME | ME_FATALERROR)))) |
| 174 | { |
| 175 | if (mem_root->error_handler) |
| 176 | (*mem_root->error_handler)(); |
| 177 | DBUG_RETURN((uchar*) 0); /* purecov: inspected */ |
| 178 | } |
| 179 | next->next= mem_root->used; |
| 180 | next->size= length; |
| 181 | mem_root->used= next; |
| 182 | DBUG_PRINT("exit",("ptr: 0x%lx", (long) (((char*) next)+ |
| 183 | ALIGN_SIZE(sizeof(USED_MEM))))); |
| 184 | DBUG_RETURN((uchar*) (((char*) next)+ALIGN_SIZE(sizeof(USED_MEM)))); |
| 185 | #else |
| 186 | size_t get_size, block_size; |
| 187 | uchar* point; |
| 188 | reg1 USED_MEM *next= 0; |
| 189 | reg2 USED_MEM **prev; |
| 190 | DBUG_ENTER("alloc_root"); |
| 191 | DBUG_PRINT("enter",("root: 0x%lx", (long) mem_root)); |
| 192 | DBUG_ASSERT(alloc_root_inited(mem_root)); |
| 193 | |
| 194 | DBUG_EXECUTE_IF("simulate_out_of_memory", |
| 195 | { |
| 196 | /* Avoid reusing an already allocated block */ |
| 197 | if (mem_root->error_handler) |
| 198 | (*mem_root->error_handler)(); |
| 199 | DBUG_SET("-d,simulate_out_of_memory"); |
| 200 | DBUG_RETURN((void*) 0); /* purecov: inspected */ |
| 201 | }); |
| 202 | length= ALIGN_SIZE(length); |
| 203 | if ((*(prev= &mem_root->free)) != NULL) |
| 204 | { |
| 205 | if ((*prev)->left < length && |
| 206 | mem_root->first_block_usage++ >= ALLOC_MAX_BLOCK_USAGE_BEFORE_DROP && |
| 207 | (*prev)->left < ALLOC_MAX_BLOCK_TO_DROP) |
| 208 | { |
| 209 | next= *prev; |
| 210 | *prev= next->next; /* Remove block from list */ |
| 211 | next->next= mem_root->used; |
| 212 | mem_root->used= next; |
no test coverage detected