ssize_t proto_h16::calc_size(MessageBlock& mb) const { uint32_t sz; if (mb.size() < sizeof(sz)) { size_t left = sizeof(sz) - mb.size(); memcpy(&sz, mb.rptr(), mb.size()); MessageBlock* cont = mb.cont(); if (cont != NULL && cont->size() >= left) { memcpy((byte *)&sz + mb.size(), cont->rptr(), left); } else { return 0; } } else { memcpy(&sz, mb.rptr(), sizeof(sz)); } if (sz >= head_size() && sz >= min_ && sz <= max_) return sz; errno = EINVAL; return -1; }
/* ============================================================================ * Resolve given a pointer, find header. Pointer may point inside data. * * We will find the header pointing at the pointer, or the nearest one below, * in case we are pointing inside a routine. 'The Price Is Right' rules apply. * */ HINDEX head_resolve(TOKEN* ptr,U32* poffset){ //sprintf("head_resolve %p %p\n",ptr,poffset); if(!ptr){ //TODO: can this happen? if(poffset) *poffset=0; return 0; } HINDEX h=(HINDEX)lay->head_bottom; HINDEX best_hindex=h; U32 best_offset = 0xFFFFFFFF; //traverse the dictionary brute force style, disregarding hierarchy. while(h < (HINDEX)var->head_ptr){ //printf("head_resolve1 %p \n",h); TOKEN* target = h->pcode; //header points here. //printf("head_resolve2 %p \n",target); //if target is below the pointer, track offset (if it's better) if((target > lay->data_bottom) && (target <= ptr)) { if((ptr-target)<best_offset){ best_offset = (ptr-target); best_hindex=h; } } //step to next head h = (HINDEX)(head_size(h) + (U32)h); } //finally, return the best match if(poffset) *poffset = best_offset; return best_hindex; }
HINDEX head_seq(head_proc func,void* params){ HINDEX h=(HINDEX)lay->head_bottom; while(h < (HINDEX)var->head_ptr){ int ret = func(h,params); if(ret) return h; h = (HINDEX)(head_size(h) + (U32)h); } return 0; }
/** * 根据request size来决定是通过small bin还是big bin还是direct 来分配内存 */ void* alloc_mem(mem_pool_t *pool,intptr_t size){ intptr_t real_size=size+head_size(); void *p; if(real_size<=SMALL_THRESHOLD){ pthread_mutex_lock(&(pool->small_mutex)); p=get_available(pool->small_bin,real_size,SMALL_THRESHOLD,pool); pthread_mutex_unlock(&(pool->small_mutex)); }else if(real_size<=BIG_THRESHOLD){ pthread_mutex_lock(&(pool->big_mutex)); p=get_available(pool->big_bin,real_size,BIG_THRESHOLD,pool); pthread_mutex_unlock(&(pool->big_mutex)); }else{ pthread_mutex_lock(&(pool->direct_mutex)); p=direct_alloc(&(pool->direct_head),real_size,pool); pthread_mutex_unlock(&(pool->direct_mutex)); } return p; }
HINDEX head_nextup(HINDEX h){ return (HINDEX)( ((U32)h) + head_size(h) ); }