init malloc and return a qm_block*/
| 183 | |
| 184 | /* init malloc and return a qm_block*/ |
| 185 | struct qm_block *qm_malloc_init(char *address, unsigned long size, char *name) |
| 186 | { |
| 187 | char *start; |
| 188 | char *end; |
| 189 | struct qm_block *qm; |
| 190 | unsigned long init_overhead; |
| 191 | int h; |
| 192 | |
| 193 | /* make address and size multiple of 8*/ |
| 194 | start=(char*)ROUNDUP((unsigned long) address); |
| 195 | LM_DBG("QM_OPTIMIZE=%lu, /ROUNDTO=%lu, %lu-bytes aligned\n", |
| 196 | Q_MALLOC_OPTIMIZE, Q_MALLOC_OPTIMIZE/QM_ROUNDTO, |
| 197 | (unsigned long)QM_ROUNDTO); |
| 198 | LM_DBG("QM_HASH_SIZE=%lu, qm_block size=%zu, frag_size=%zu\n", |
| 199 | QM_HASH_SIZE, sizeof(struct qm_block), FRAG_OVERHEAD); |
| 200 | LM_DBG("params (%p, %lu), start=%p\n", address, size, start); |
| 201 | if (size<start-address) return 0; |
| 202 | size-=(start-address); |
| 203 | if (size <(MIN_FRAG_SIZE+FRAG_OVERHEAD)) return 0; |
| 204 | size=ROUNDDOWN(size); |
| 205 | |
| 206 | init_overhead=ROUNDUP(sizeof(struct qm_block))+sizeof(struct qm_frag)+ |
| 207 | sizeof(struct qm_frag_end); |
| 208 | LM_DBG("size= %lu, init_overhead=%lu\n", size, init_overhead); |
| 209 | |
| 210 | if (size < init_overhead) |
| 211 | { |
| 212 | /* not enough mem to create our control structures !!!*/ |
| 213 | return 0; |
| 214 | } |
| 215 | end=start+size; |
| 216 | qm=(struct qm_block*)(void *)start; |
| 217 | memset(qm, 0, sizeof(struct qm_block)); |
| 218 | qm->name=name; |
| 219 | qm->size=size; |
| 220 | qm->used=size-init_overhead; |
| 221 | qm->fragments = 0; |
| 222 | |
| 223 | qm->real_used=size; |
| 224 | qm->max_real_used = 0; |
| 225 | size-=init_overhead; |
| 226 | |
| 227 | qm->first_frag=(struct qm_frag*)(void *)(start+ROUNDUP(sizeof(struct qm_block))); |
| 228 | qm->last_frag_end=(struct qm_frag_end*)(void *)end-1; |
| 229 | /* init initial fragment*/ |
| 230 | qm->first_frag->size=size; |
| 231 | qm->last_frag_end->size=size; |
| 232 | |
| 233 | #ifdef DBG_MALLOC |
| 234 | qm->first_frag->check=ST_CHECK_PATTERN; |
| 235 | qm->last_frag_end->check1=END_CHECK_PATTERN1; |
| 236 | qm->last_frag_end->check2=END_CHECK_PATTERN2; |
| 237 | #endif |
| 238 | /* init free_hash* */ |
| 239 | for (h=0; h<QM_HASH_SIZE;h++){ |
| 240 | qm->free_hash[h].head.u.nxt_free=&(qm->free_hash[h].head); |
| 241 | qm->free_hash[h].tail.prev_free=&(qm->free_hash[h].head); |
| 242 | qm->free_hash[h].head.size=0; |
no test coverage detected