void* _shm_resize( void* p , unsigned int s)
#endif
{
#ifdef VQ_MALLOC
	struct vqm_frag *f;
#endif
	if (p==0) {
		DBG("WARNING:vqm_resize: resize(0) called\n");
		return shm_malloc( s );
	}
#	ifdef DBG_QM_MALLOC
#	ifdef VQ_MALLOC
	f=(struct  vqm_frag*) ((char*)p-sizeof(struct vqm_frag));
	MDBG("_shm_resize(%p, %d), called from %s: %s(%d)\n",  
		p, s, file, func, line);
	VQM_DEBUG_FRAG(shm_block, f);
	if (p>(void *)shm_block->core_end || p<(void*)shm_block->init_core){
		LOG(L_CRIT, "BUG: vqm_free: bad pointer %p (out of memory block!) - "
				"aborting\n", p);
		abort();
	}
#endif
#	endif
	return sh_realloc( p, s ); 
}
void vqm_free(struct vqm_block* qm, void* p)
#endif
{
	struct vqm_frag *f, *next, *prev, *first_big;
	unsigned char b;

#ifdef DBG_QM_MALLOC
	DBG("vqm_free(%p, %p), called from %s: %s(%d)\n", 
		qm, p, file, func, line);
	if (p>(void *)qm->core_end || p<(void*)qm->init_core){
		LOG(L_CRIT, "BUG: vqm_free: bad pointer %p (out of memory block!) - "
				"aborting\n", p);
		abort();
	}
#endif
	if (p==0) {
		DBG("WARNING:vqm_free: free(0) called\n");
		return;
	}
	f=(struct  vqm_frag*) ((char*)p-sizeof(struct vqm_frag));
	b=f->u.inuse.bucket;
#ifdef DBG_QM_MALLOC
	VQM_DEBUG_FRAG(qm, f);
	if ( ! FRAG_ISUSED(f) ) {
		LOG(L_CRIT, "BUG: vqm_free: freeing already freed pointer,"
				" first freed: %s: %s(%d) - aborting\n",
				f->file, f->func, f->line);
		abort();
	}
	if ( b>MAX_BUCKET ) {
		LOG(L_CRIT, "BUG: vqm_free: fragment with too high bucket nr: "
				"%d, allocated: %s: %s(%d) - aborting\n",
				b, f->file, f->func, f->line); 
		abort();
	}
	DBG("vqm_free: freeing %d bucket block alloc'ed from %s: %s(%d)\n", 
		f->u.inuse.bucket, f->file, f->func, f->line);
	f->file=file; f->func=func; f->line=line;
	qm->usage[ f->u.inuse.bucket ]--;
#endif
	if (IS_BIGBUCKET(qm,b)) {
		next=FRAG_NEXT(f);
		if  ((char *)next +sizeof( struct vqm_frag) < qm->core_end) {
			VQM_DEBUG_FRAG(qm, next);
			if (! FRAG_ISUSED(next)) { /* coalesce with next fragment */
				DBG("vqm_free: coalesced with next\n");
				vqm_detach_free(qm, next);
				f->size+=next->size;
				FRAG_END(f)->size=f->size;
			}
		}
		first_big = qm->next_free[b];
		if (first_big &&  f>first_big) {
			prev=FRAG_PREV(f);
			VQM_DEBUG_FRAG(qm, prev);
			if (!FRAG_ISUSED(prev)) { /* coalesce with prev fragment */
				DBG("vqm_free: coalesced with prev\n");
				vqm_detach_free(qm, prev );
				prev->size+=f->size;
				f=prev;
				FRAG_END(f)->size=f->size;
			}
		}
		if ((char *)f==qm->big_chunks) { /* release unused core */
			DBG("vqm_free: big chunk released\n");
			qm->free_core+=f->size;
			qm->big_chunks+=f->size;
			return;
		}		
		first_big = qm->next_free[b];
		/* fix reverse link (used only for BIG_BUCKET */
		if (first_big) FRAG_END(first_big)->prv_free=f;
		FRAG_END(f)->prv_free=0;
	} else first_big = qm->next_free[b];
	f->u.nxt_free = first_big; /* also clobbers magic */
	qm->next_free[b] = f;
}
void* vqm_malloc(struct vqm_block* qm, unsigned int size)
#endif
{
	struct vqm_frag *new_chunk, *f;
	unsigned char bucket;
	
#ifdef DBG_QM_MALLOC
	unsigned int demanded_size;
	DBG("vqm_malloc(%p, %d) called from %s: %s(%d)\n", qm, size, file,
	 func, line);
	demanded_size = size;
#endif
	new_chunk=0;
    	/* what's the bucket? what's the total size incl. overhead? */
	bucket = size2bucket( qm, &size );

	if (IS_BIGBUCKET(qm, bucket)) {	/* the kilo-bucket uses first-fit */
#ifdef DBG_QM_MALLOC
		DBG("vqm_malloc: processing a big fragment\n");
#endif
		for (f=qm->next_free[bucket] ; f; f=f->u.nxt_free ) 
			if (f->size>=size) { /* first-fit */
				new_chunk=f;
				VQM_DEBUG_FRAG(qm, f);
				vqm_detach_free(qm,f);
				break;
			}
	} else if (  (new_chunk=qm->next_free[ bucket ]) ) { /*fixed size bucket*/
			VQM_DEBUG_FRAG(qm, new_chunk);
			/*detach it from the head of bucket's free list*/
			qm->next_free[ bucket ] = new_chunk->u.nxt_free;
	}

	if (!new_chunk) { /* no chunk can be reused; slice one from the core */
		new_chunk=MORE_CORE( qm, bucket, size );
		if (!new_chunk) {
#ifdef DBG_QM_MALLOC
			LOG(L_DBG, "vqm_malloc(%p, %d) called from %s: %s(%d)\n", 
				qm, size, file, func, line);
#else
			LOG(L_DBG, "vqm_malloc(%p, %d) called from %s: %s(%d)\n", 
				qm, size);
#endif
			return 0;
		}
	}
	new_chunk->u.inuse.magic = FR_USED;
	new_chunk->u.inuse.bucket=bucket;
#ifdef DBG_QM_MALLOC
	new_chunk->file=file;
	new_chunk->func=func;
	new_chunk->line=line;
	new_chunk->demanded_size=demanded_size;
	qm->usage[ bucket ]++;
	DBG("vqm_malloc( %p, %d ) returns address %p in bucket %d, real-size %d\n",
		qm, demanded_size, (char*)new_chunk+sizeof(struct vqm_frag), 
		bucket, size );

	new_chunk->end_check=(char*)new_chunk+
							sizeof(struct vqm_frag)+demanded_size;
	memcpy(  new_chunk->end_check, END_CHECK_PATTERN, END_CHECK_PATTERN_LEN );
	new_chunk->check=ST_CHECK_PATTERN;
#endif
	return (char*)new_chunk+sizeof(struct vqm_frag);
}