Esempio n. 1
0
static void qjoin(qarena_t *arena) {
	void *p = arena+1;
	void *end = (char *)arena + arena->size;
	while (p && p < end) {
		if (NX(p) < end && ISFREE(p) && ISFREE(NX(p))) {
			SZ(p) += BSZ(NX(p));
		} else {
			p = NX(p);
		}
	}
}
Esempio n. 2
0
PMemBlock mmAllocMem( memHeap_t *heap, int size, int align2, int startSearch)
{
  int mask,startofs,endofs;
  TMemBlock *p;

  if (!heap || align2 < 0 || size <= 0)
    return NULL;
  mask = (1 << align2)-1;
  startofs = 0;
  p = (TMemBlock *)heap;
  while (p) {
    if (ISFREE(p)) {
      startofs = (p->ofs + mask) & ~mask;
      if ( startofs < startSearch ) {
      	startofs = startSearch;
      }
      endofs = startofs+size;
      if (endofs <= (p->ofs+p->size))
	break;
    }
    p = p->next;
  }
  if (!p)
    return NULL;
  p = SliceBlock(p,startofs,size,0,mask+1);
  p->heap = heap;
  return p;
}
Esempio n. 3
0
/****************************
* remove block from free list
* the block might still be under construction, so no check_block()
*/
static void rem_free( tMemHdr *const tr )
{
register tMemHdr *t0 = tr->prev_list;
register tMemHdr *t1 = tr->next_list;

   assert( head_mem != NULL );	/* the cache exists */ 
   assert( tr->magic == MAGIC );
   assert( ISFREE(tr) );
   assert( tr->next_mem == NULL || tr->next_mem->prev_mem == tr);
   assert( tr->prev_mem == NULL || tr->prev_mem->next_mem == tr);

   if( t1 != NULL ) {
      assert( tr->size >= t1->size );	/* decreasing size */
      t1->prev_list = t0;
   } /* if */
   if( t0 != NULL ) {
      assert( tr->size <= t0->size );	/* decreasing size */
      t0->next_list = t1;
   }
   else {
      head_free = t1;
   } /* if */

   assert( tr->next_mem == NULL || tr->next_mem->prev_mem == tr);
   assert( tr->prev_mem == NULL || tr->prev_mem->next_mem == tr);

} /* rem_free() */
Esempio n. 4
0
int _RTLENTRY _EXPFUNC _rtl_heapwalk(_HEAPINFO * __entry)
{
    HEAP *h;
    BLOCKHDR *bh;

    if (IS_BIG_BLOCK(__entry))  /* We won't attempt to walk BIG Blocks */
        return _HEAPEND;

    _lock_heap();
    if (__entry->_pentry == NULL)
    {
	h = _firstHeap;
	bh = FIRSTBLOCK(h);
    }
    else
    {
	h = (HEAP *) __entry->_pentry;
	bh = (BLOCKHDR *) __entry->__pentry;
    }

    while (h)
    {
	if (__memBogusAddr(h))
	    return _HEAPBADPTR;

	while (HDR2PTR(bh) != ((char *) h + h->cSize))
	{
	    if (__memBogusAddr(bh))
		return _HEAPBADPTR;

	    __entry->_useflag = (ISFREE(bh) == 0);
	    __entry->_size = SIZE(bh);

	    bh = NEXT(bh);
	    __entry->_pentry = (void *) h;
	    __entry->__pentry = (void *) bh;
	    _unlock_heap();
	    return _HEAPOK;
	}
	h = h->nextHeap;
	if (h)
	    bh = FIRSTBLOCK(h);
    }
    _unlock_heap();
    return _HEAPEND;
}
Esempio n. 5
0
int mmReserveMem(memHeap_t *heap, int offset,int size)
{
  int endofs;
  TMemBlock *p;

  if (!heap || size <= 0)
    return -1;
  endofs = offset+size;
  p = (TMemBlock *)heap;
  while (p && p->ofs <= offset) {
    if (ISFREE(p) && endofs <= (p->ofs+p->size)) {
      SliceBlock(p,offset,size,1,1);
      return 0;
    }
    p = p->next;
  }
  return -1;
}
Esempio n. 6
0
/****************************
* add block to free list
* check_block() is called when block added to free list
*/
static void add_free( tMemHdr *const tr )
{
register tMemHdr *t0;
register tMemHdr *t1;

   assert( tr != NULL );
   assert( tr->magic == MAGIC );
   assert( ISFREE(tr) );

   /** find where to put tr into free list **/

   t0 = NULL;
   t1 = head_free;
   while( t1 != NULL && t1->size > tr->size ) {
      assert( t1->next_list == NULL || t1->next_list->prev_list == t1 );
      assert( t1->prev_list == t0 );
      t0 = t1;
      t1 = t1->next_list;
      assert( t0 != NULL );
   } /* while */

   tr->next_list = t1;
   tr->prev_list = t0;
   if( t1 != NULL ) {
      t1->prev_list = tr;
   } /* if */
   if( t0 == NULL ) {
      /* the free list is empty, or this is the largest block */
      head_free = tr;
   }
   else {
      t0->next_list = tr;
   } /* if */

   assert( head_free != NULL );
   assert( t1 == NULL || t1->next_list == NULL || t1->next_list->prev_list == t1 );
   assert( t1 == NULL || t1->prev_list == NULL || t1->prev_list->next_list == t1 );
   assert( tr->next_list == NULL || tr->next_list->prev_list == tr );
   assert( tr->prev_list == NULL || tr->prev_list->next_list == tr );
   assert( check_block( tr ) );

} /* add_free() */
Esempio n. 7
0
static void 
angel_FreeToPool(int n)
{
    angel_TaskQueueItem *my_tqi = &angel_TQ_Pool[n];
    angel_TaskQueueItem *tqi, *l_tqi;

    if (ISFREE(n))
        LogError(LOG_SERLOCK, ( "Attempt to deallocate free block %d.\n", n));

    FREE(n);

    /* Now we find it on the queue and remove it */
    for (tqi = angel_TaskQueueHead, l_tqi = NULL;
         (tqi != my_tqi && tqi != NULL);)
    {
        l_tqi = tqi;
        tqi = tqi->next;
    }

    if (tqi == NULL)
    {
        LogError(LOG_SERLOCK, ( "Block could not be dequeued (%d).\n", n));
        return;
    }

#ifdef DO_TRACE
    LogTrace(LOG_SERLOCK, "SFreePool: %d\n", n);
#endif

    if (l_tqi == NULL)
        angel_TaskQueueHead = my_tqi->next;
    else
        l_tqi->next = my_tqi->next;
    my_tqi->next = NULL;

}
Esempio n. 8
0
void *qalloc(qarena_t *arena, unsigned size) {
	void *p = arena+1;
	void *end = (char *)arena + arena->size;
	void *n = NULL;

	size = RNDSZ(size);
	
	while (p && p < end) {
		if (!ISFREE(p) || BSZ(p) < size) {
			p = NX(p);
			continue;
		}

		if (BSZ(p) > size) {
			n = (char*)p + size;
			SZ(n) = SZ(p) - size;
			SZ(p) = size;
		}

		ALLOC(p);
		return UPTR(p);
	}
	return NULL;
}
Esempio n. 9
0
void CHeap1::Free( void* mem ) {
	Node* Tofree = (Node*)( (char*)mem - sizeof(Node) );
	mem = NULL;

	if ( !CheckNode( Tofree ) ) {
		// This is not a vilide node, something wrong
		return;
	}

	// because sentinel is always exsit as a free node, so any node in freelist will at least has one p*Free != NULL
#define ISFREE( node ) ( CheckNode( node ) && node->pPrevFree != NULL || node->pNextFree != NULL )
	Node* Prev = Tofree->pPrevMem;
	Node* Next = Tofree->pNextMem;
	Node* node = Tofree;

	if ( Prev == pSentinel ) {
		if ( ISFREE( Next ) ) {
			node->pPrevFree = Next->pPrevFree;
			node->pNextFree = Next->pNextFree;

			Next->pPrevFree->pNextFree = node;
			if ( Next->pNextFree ) Next->pNextFree->pPrevFree = node;

			node->pNextMem = Next->pNextMem;
			if ( Next->pNextMem <= pHeapEnd ) node->pNextMem->pPrevMem = node;
		}
		else {
			Tofree->pNextFree = pSentinel->pNextFree;
			Tofree->pPrevFree = pSentinel;
			if ( pSentinel->pNextFree ) pSentinel->pNextFree->pPrevFree = Tofree;
			pSentinel->pNextFree = Tofree;
		}
		return;
	}

	if ( ISFREE( Prev ) && ISFREE( Next ) ) {
		// Prev and Next both in FreeList
		Next->pPrevFree->pNextFree = Next->pNextFree;
		if ( Next->pNextFree ) Next->pNextFree->pPrevFree = Next->pPrevFree;

		Prev->pNextMem = Next->pNextMem;
		if ( Next->pNextMem <= pHeapEnd ) Next->pNextMem->pPrevMem = Prev;
	}
	else if ( ISFREE( Prev ) ) {
		Prev->pNextMem = node->pNextMem;
		if ( node->pNextMem <= pHeapEnd ) node->pNextMem->pPrevMem = Prev;
	}
	else if ( ISFREE( Next ) ) {
		node->pPrevFree = Next->pPrevFree;
		node->pNextFree = Next->pNextFree;

		Next->pPrevFree->pNextFree = node;
		if ( Next->pNextFree ) Next->pNextFree->pPrevFree = node;

		node->pNextMem = Next->pNextMem;
		if ( Next->pNextMem <= pHeapEnd ) node->pNextMem->pPrevMem = node;
	}
	else {
		// merge failed
		Tofree->pNextFree = pSentinel->pNextFree;
		Tofree->pPrevFree = pSentinel;
		if ( pSentinel->pNextFree ) pSentinel->pNextFree->pPrevFree = Tofree;
		pSentinel->pNextFree = Tofree;
	}
	return;
#undef ISFREE
}
Esempio n. 10
0
static int 
angel_AllocateFromPool(angel_TaskPriority pri, bool new_task,
                       bool yielded)
{
    int i;

    for (i = 0; i < POOLSIZE; i++)
    {
        if (ISFREE(i))
        {
            angel_TaskQueueItem *my_tqi = &angel_TQ_Pool[i];
            angel_TaskQueueItem *tqi, *l_tqi;

#ifdef DO_TRACE
            LogTrace(LOG_SERLOCK, "SAllocPool: %d-p%d-n%d\n", i, pri, new_task);
#endif

            ALLOC(i);

            /* Set up the priorities */
            my_tqi->pri = pri;
            my_tqi->new_task = new_task;

            /* And insert the item into the queue.
             * which first involves finding a task of same priority and
             * inserting this task before it if not new, or after it if new.
             */

            /* if new or yielded, ensure it goes after any exisiting entry at pri */
            if (new_task || yielded)
                pri = (angel_TaskPriority) (pri - 1);

            for (tqi = angel_TaskQueueHead, l_tqi = NULL;
                 (tqi != NULL) && (tqi->pri > pri);)
            {
                l_tqi = tqi;
                tqi = tqi->next;
            }

            /* We may have reached the end of the list, or we may not have */
            my_tqi->next = tqi;
            if (l_tqi == NULL)
                angel_TaskQueueHead = my_tqi;
            else
                l_tqi->next = my_tqi;
            
            /* LogInfo(LOG_SERLOCK, ( "Allocated RegBlock %d\n",i)); */

            return i;
        }
    }
    LogError(LOG_SERLOCK, ( "AllocateFromPool: No free RegBlock\n"));
#if DEBUG == 1
    /*
     * for (i = 0; i < POOLSIZE; i++)
     *{
     *  angel_TaskQueueItem *my_tqi = &angel_TQ_Pool[i];
     *
     *  LogWarning(LOG_SERLOCK, ( "Task %d: Pri=%d, New=%d, PC=%8x, PSR=%08x\n",
     *                              i, my_tqi->pri, my_tqi->new_task,
     *                              my_tqi->rb.r[15], my_tqi->rb.cpsr));
     *}
     */
#endif
    return -1;
}
Esempio n. 11
0
/*********************************************
* create new block of requested size by removing oldest memory blocks
* block contents are not initialised
* size is rounded up to exact nr longs
* base for removed blocks is set to NULL
* *pbase := adr of block, 
*       or null if cache is unable to supply enough memory
* return null
*/
void find_mem( uint32 rq_size, void **const base )
{
register tMemHdr *tr;
register tMemHdr *t0;
register tMemHdr *t1;

   assert( head_mem != NULL );	/* there must be a cache !! */
   assert( base != NULL );

   assert( rq_size <= ((rq_size+3)&~3) );
   assert( rq_size+4 > ((rq_size+3)&~3) );
   rq_size = (rq_size+3)&~3;

   if(( rq_size > total_size) ) {
      /* request fails - it is too large for cache */
      dprintf(( "requested mem (%ld) larger than cache size (%ld)\n", rq_size, total_size ));
      *base = NULL;
      return;
   } /* if */

   /** loop to remove old data until there is enough free space for current request **/

   dprintf(( "rq_size is %ld\n", (long)rq_size ));
   assert( head_free != NULL || total_free == 0 );

   /* note the special case when total free == 0 (so head_free == NULL)
   ** and rq_size is 0. */

   while( rq_size > total_free || total_free == 0 ) {

      dprintf(("need to remove lru data block(%ld), size (%ld)\n", (long)head_data->data[0], (long)head_data->size ));
      assert( head_data != NULL || rq_size <= total_free );
      assert( total_free + total_used + (nr_blocks-1)*sizeof(tMemHdr) == total_size );

      assert( head_data->prev_list == NULL );
      release_block( head_data );      /* remove lru data block */

      assert( head_data != NULL || rq_size <= total_free );
      assert( head_data != NULL || total_used == 0 );
      assert( head_data == NULL || head_data->prev_list == NULL);

   } /* while */

   assert( total_free >= rq_size );
   assert( head_free != NULL );

   /**********************************************************
   * there is now enough space in the cache to fulfil the request
   * but it may need to be gathered together into one block
   * move all data blocks down to the start of the cache 
   * this leaves one free block at the end of the cache
   **********************************************************/

   if( head_free->size < rq_size ) {
   register uint32 *free_p;	/** free space pointer **/

      /* the memory is fragmented, so move all data down memory
      ** to concentrate the free mem into one block at the end
      ** note: fragmented ==> at least one data block & 2 free blocks */

      #ifdef TEST
      conc++;
      dprintf(( "concentrating data...(this is the %ldth time)\n", conc ));
      #endif

      assert( head_data != NULL );

      t1 = head_mem;
      while( ISDATA(t1) ) {
         assert( check_block(t1) );
         assert( t1->next_mem != NULL );	/* there are at least two free blocks following */
         t1 = t1->next_mem;
      } /* while */

      assert( ISFREE(t1) );

      free_p = (uint32*)t1;   		/* the first free area */
      t0 = t1->prev_mem;	   /* the last data block so far, or NULL */
      assert( t0 == NULL || check_block(t0) );
      assert( t0 == NULL || ISDATA(t0) );
      assert( t0 == NULL || (uint32*)free_p == (uint32*)(t0->next_mem) );

      /** loop to copy data blocks down
      **  t1 scans thru mem blocks,
      **  t0 follows one behind, it is the latest concentrated block
      **/
      do {
         assert( t1->magic == MAGIC ); /* t1->prev?? may have been overwritten */
         if( ISDATA(t1) ) {
         register int32 i = t1->size + sizeof(tMemHdr); /* nr bytes to move */
         register uint32 *s1 = (uint32*)t1;             /* src address */

            /**** 
            ** move data block at t1 down to free_p, 
            ** adjust t0 = new conc'd data block, adjust t1
            *****/

            assert( t0 == NULL || (uint32*)free_p == (uint32*)(t0->next_mem) );

            tr = (tMemHdr*) free_p;  /* relocate block pointer */
            assert( tr != NULL );
            assert( tr < t1 );	/* there is a gap between end of t0 & start of t1 */
            t1 = t1->next_mem;	/* data at t1 will be overwritten if data size > gap too free_p */

            assert( (i&3) == 0 );	/* data & header both exact nr longs */
            i >>= 2; /* nr longs */
            while( --i >= 0 ) {	/* copy header & data of block */
               *free_p++ = *s1++;
            } /* if */

            /* note: free_p now points to new free area, at end of tr */

            assert( (uint32)tr->data + tr->size == (uint32)free_p );

            *tr->pbase = tr->data;
            tr->next_mem = (tMemHdr*)free_p;	/* adjust links */
            tr->prev_mem = t0;
            assert( (t0 == NULL && tr == head_mem) || t0->next_mem == tr );
            if( tr->next_list != NULL ) {
               tr->next_list->prev_list = tr;
            }
            else {
               tail_data = tr;
            } /* if */
            if( tr->prev_list != NULL ) {
               tr->prev_list->next_list = tr;
            }
            else {
               head_data = tr;
            } /* if */

            t0 = tr;
            assert( ISDATA(t0) );
            assert( check_block(t0) );
            assert( t0->prev_mem == NULL || t0->prev_mem->next_mem == t0);
         }
         else {
            nr_blocks--;   /* removed a free block */
            total_free += sizeof(tMemHdr);
            t1 = t1->next_mem;
         } /* if */
      } while( t1 != NULL );
      assert( t0 != NULL );

      /** now create one free block at the end of the cache */

      t1 = head_free = t0->next_mem;
      assert( head_free == (tMemHdr*)free_p );
      t1->next_mem = t1->next_list = t1->prev_list = NULL;
      t1->prev_mem = t0;
      total_free -= sizeof(tMemHdr);
      assert( total_free == (uint32)head_mem + total_size - (uint32)t1);
      t1->size = total_free;
      t1->pbase = NULL;
      #ifndef NDEBUG
      t1->magic = MAGIC;
      t1->data[0] = -2;
      #endif

      nr_blocks++;
      assert( total_free + total_used + (nr_blocks-1)*sizeof(tMemHdr) == total_size );
   } /* if */
Esempio n. 12
0
/*************************************************************
* move a block of memory from the data chain to the free chain
* merge with next & previous blocks if possible
*/
static void release_block( register tMemHdr *tr )
{
register tMemHdr *t0;
register tMemHdr *t1;
   assert( tr == NULL || tr->next_mem == NULL || tr->next_mem->prev_mem == tr );
   assert( tr == NULL || tr->prev_mem == NULL || tr->prev_mem->next_mem == tr );
   assert( tr == NULL || tr->next_list == NULL || tr->next_list->prev_list == tr );
   assert( tr == NULL || tr->prev_list == NULL || tr->prev_list->next_list == tr );
   assert( check_block(tr) );
   assert( ISDATA(tr) );
   total_free += tr->size;
   total_used -= tr->size;
   *tr->pbase = NULL;       /* tell application this block has been released */
   tr->pbase = NULL;        /* flag this block as free */
   t0 = tr->prev_list;
   t1 = tr->next_list;
   if( t0 == NULL ) {
      head_data = t1;
   }
   else {
      t0->next_list = t1;
   } /* if */
   if( t1 == NULL ) {
      tail_data = t0;
   }
   else {
      t1->prev_list = t0;
   } /* if */

   /** block removed from data chain, now try merge with next, previous **/

   t1 = tr->next_mem;
   if( t1 != NULL && ISFREE(t1) ) {

      /** we can absorb the next mem block **/
      #ifdef TEST
      merged_next++;
      dprintf(( "merging block(%ld, size %ld) & following(%ld, size %ld)\n", (long)tr->data[0], (long)tr->size, (long)tr->next_mem->data[0], (long)tr->next_mem->size ));
      #endif

      rem_free( t1 );    /** remove next from free list **/

      /** remove tr->next_mem from memory list **/
      tr->size += t1->size + sizeof(tMemHdr);
      tr->next_mem = t0 = t1->next_mem;
      if( t0 != NULL ) {
         t0->prev_mem = tr;
      } /* if */

      assert( tr->next_mem == NULL || tr->next_mem->prev_mem == tr );
      assert( tr->next_mem == NULL || (uint32)tr + sizeof(tMemHdr) + tr->size == (uint32)tr->next_mem );

      dprintf(( "size of merged block is %ld\n", (long)tr->size ));
      total_free += sizeof( tMemHdr );
      nr_blocks--;
   } /* if */
   assert( total_free + total_used + (nr_blocks-1)*sizeof(tMemHdr) == total_size );

   t0 = tr->prev_mem;
   if( t0 != NULL && ISFREE(t0) ) {

      /** we can merge into the prev mem block **/

      #ifdef TEST
      dprintf(( "merging block(%ld, size %ld) & previous(%ld, size %ld)\n", (long)tr->data[0], (long)tr->size, (long)tr->prev_mem->data[0], (long)tr->prev_mem->size ));
      merged_prev++;
      #endif

      rem_free( t0 );     /** remove prev from free list **/

      /** remove tr from memory list **/
      t1 = t0->next_mem = tr->next_mem;
      if( t1 != NULL ) {
         t1->prev_mem = t0;
      } /* if */
      assert( t0->next_mem == NULL || t0->next_mem->prev_mem == t0 );
      assert( t1 == NULL || t1->prev_mem->next_mem == t1 );

      t0->size += tr->size + sizeof( tMemHdr );
      total_free += sizeof( tMemHdr );
      nr_blocks--;

      tr = t0;	/* tr is adr of merged block */
      dprintf(( "size of merged block is %ld\n", (long)tr->size ));
      assert( tr->next_mem == NULL || (uint32)tr + sizeof(tMemHdr) + tr->size == (uint32)tr->next_mem );
      assert( tr->next_mem == NULL || tr->next_mem->prev_mem == tr);
   } /* if */

   assert( total_free + total_used + (nr_blocks-1)*sizeof(tMemHdr) == total_size );

   add_free( tr );
   assert( check_cache() );
} /* release_block() */
Esempio n. 13
0
static int check_cache( void )
{
int result = 1;
uint16 nd, nd1;
uint16 nf, nf1;
uint32 tf, tf1;
uint32 td, td1;
tMemHdr *t;

   /** run thru mem list ... */
   nd1= nf1 = 0;
   tf1 = td1 = 0;
   t = head_mem;
   if( t == NULL ) {
      dprintf(( "head_mem is NULL!!, cache doesn't exist\n" ));
      return 1;
   } /* if */

   while( t != NULL ) {
      if( check_block(t) == 0 ) result = 0;
      if( ISDATA(t) ) {
         nd1++;
         td1 += t->size;
      }
      else {
         nf1++;
         tf1 += t->size;
      } /* if */
      t->magic = 0;
      if( t->next_mem != NULL && (uint32)(t+1) + t->size != (uint32)t->next_mem  ) {
         dprintf(( "memory block(%ld) & next are not contiguous\n", (long)t->data[0] ));
         result = 0;
      } /* if */
      if( t->prev_mem != NULL && (uint32)(t->prev_mem+1) + t->prev_mem->size != (uint32)t ) {
         dprintf(( "memory block(%ld) & prev are not contiguous\n", (long)t->data[0] ));
         result = 0;
      } /* if */
      if( t->next_mem != NULL && t->next_mem->prev_mem != t) {
         dprintf(( "memory block(%ld) next doesn't link back\n", (long)t->data[0] ));
         result = 0;
      } /* if */
      if( t->prev_mem != NULL && t->prev_mem->next_mem != t) {
         dprintf(( "memory block(%ld) prev doesn't link back\n", (long)t->data[0] ));
         result = 0;
      } /* if */
      if( t->next_mem == NULL && (uint32)(t+1) + t->size != (uint32)(head_mem+1) + total_size ) {
         dprintf(( "last memory block(%ld) in wrong place\n", (long)t->data[0] ));
         result = 0;
      } /* if */
      t = t->next_mem;
   } /* while */
   if( nd1 + nf1 != nr_blocks ) {
      dprintf(( "nr_blocks count is %d, counted %d\n", nr_blocks, nd1+nf1 ));
      result = 0;
   } /* if */
   if( tf1 != total_free ) {
      dprintf(( "total_free is %ld, counted %ld\n", total_free, tf1 ));
      result = 0;
   } /* if */

   /** run thru free list ... */
   nf = 0;
   tf = 0;
   t = head_free;
   while( t != NULL ) {
      nf++;
      tf += t->size;
      if( t->magic != 0 ) {
         dprintf(( "memory block(%ld) in free list, not in mem list\n", (long)t->data[0] ));
         result = 0;
      } /* if */
      t->magic = MAGIC;
      if( !ISFREE(t) ) {
         dprintf(( "free memory block(%ld) marked as data\n", (long)t->data[0] ));
         result = 0;
      } /* if */
      if( t->next_list != NULL && t->next_list->size > t->size ) {
         dprintf(( "free memory block(%ld) smaller than next\n", (long)t->data[0] ));
         result = 0;
      } /* if */
      if( t->prev_list != NULL && t->prev_list->size < t->size ) {
         dprintf(( "free memory block(%ld) larger than prev\n", (long)t->data[0] ));
         result = 0;
      } /* if */
      if( t->prev_list != NULL && t->prev_list->next_list != t ) {
         dprintf(( "free memory block(%ld) doesn't link back\n", (long)t->data[0] ));
         result = 0;
      } /* if */
      if( t->next_list != NULL && t->next_list->prev_list != t ) {
         dprintf(( "free memory block(%ld) doesn't link forward\n", (long)t->data[0] ));
         result = 0;
      } /* if */
      t = t->next_list;
   } /* while */
   if( nf != nf1 ) {
      dprintf(( "miscounted free blocks, mem chain ==> %d, free list ==> %d\n", nf1, nf ));
      result = 0;
   } /* if */
   if( tf != tf1 ) {
      dprintf(( "miscounted free mem, mem chain ==> %ld, free list ==> %ld\n", tf1, tf ));
      result = 0;
   } /* if */
   if( tf != total_free ) {
      dprintf(( "total_free is %ld, counted %ld\n", total_free, tf ));
      result = 0;
   } /* if */

   /** run thru data list ... */
   nd = 0;
   td = 0;
   t = head_data;
   if( (head_data == NULL) != (tail_data == NULL) ) {
      dprintf(( "head_data & tail_data disagree\n" ));
      result = 0;
   } /* if */
   while( t != NULL ) {
      nd++;
      td += t->size;
      if( t->magic != 0 ) {
         dprintf(( "memory block(%ld) in data list, not in mem list\n", (long)t->data[0] ));
         result = 0;
      } /* if */
      t->magic = MAGIC;
      if( ISFREE(t) ) {
         dprintf(( "data memory block(%ld) marked as free\n", (long)t->data[0] ));
         result = 0;
      } /* if */
      if( t->prev_list == NULL && t != head_data ) {
         dprintf(( "block(%ld) with null prev link not at head\n", (long)t->data[0] ));
         result = 0;
      } /* if */
      if( t->next_list == NULL && t != tail_data ) {
         dprintf(( "block(%ld) with null next link not at tail\n", (long)t->data[0] ));
         result = 0;
      } /* if */
      if( t->prev_list != NULL && t->prev_list->next_list != t ) {
         dprintf(( "data memory block(%ld) doesn't link back\n", (long)t->data[0] ));
         result = 0;
      } /* if */
      if( t->next_list != NULL && t->next_list->prev_list != t ) {
         dprintf(( "data memory block(%ld) doesn't link forward\n", (long)t->data[0] ));
         result = 0;
      } /* if */
      if( *t->pbase != t->data ) {
         dprintf(( "base block(%ld) doesn't link to data\n", (long)t->data[0] ));
         result = 0;
      } /* if */
      t = t->next_list;
   } /* while */
   if( nd != nd1 ) {
      dprintf(( "miscounted data blocks, mem chain ==> %d, free list ==> %d\n", nd1, nd ));
      result = 0;
   } /* if */
   if( td != td1 ) {
      dprintf(( "miscounted data mem, mem chain ==> %ld, free list ==> %ld\n", td1, td ));
      result = 0;
   } /* if */
   if( td != total_used ) {
      dprintf(( "total_used is %ld, counted %ld\n", total_used, td ));
      result = 0;
   } /* if */

   if( nd+nf != nr_blocks ) {
      dprintf(( "lost blocks, nr blocks is %d, nd is %d, nf is %d\n", nr_blocks, nd, nf ));
      result = 0;
   } /* if */

   t = head_mem;
   while( t != NULL ) {
      if( t->magic != MAGIC ) {
         dprintf(( "memory block(%ld) is lost\n", (long)t->data[0] ));
         result = 0;
      } /* if */
      t = t->next_mem;
   } /* while */

   return result;

} /* check_cache() */
Esempio n. 14
0
/**************************************
* functions to check block and cache for consistency
* return 1 if OK, 0 if failure found
*/
static int check_block( tMemHdr *t )
{
int result = 1;
   if( t == NULL ) {
      dprintf(( "memory block is NULL\n" ));
      return head_mem == NULL;
   } /* if */

   if( t->magic != MAGIC ) {
      dprintf(("memory block(%ld) has no magic number\n", (long)t->data[0] ));
      result = 0;
   } /* if */
   if( (t->size & 3) != 0 ) {
      dprintf(("memory block(%ld) size is %ld, sb exact nr longs\n", (long)t->data[0], (long)t->size ));
      result = 0;
   } /* if */
   if( t->size > total_size ) {
      dprintf(("memory block(%ld) size is out of range (%ld)\n", (long)t->data[0], (long)t->size ));
      result = 0;
   } /* if */
   if( t->next_mem != NULL && t->next_mem < t + 1 ){
      dprintf(("memory block(%ld) next mem is wrong\n", (long)t->data[0] ));
      result = 0;
   } /* if */
   if( t->prev_mem != NULL && t->prev_mem >= t ){
      dprintf(("memory block(%ld) prev mem is wrong\n", (long)t->data[0] ));
      result = 0;
   } /* if */
   if( t->next_mem != NULL && (uint32)t->data + t->size != (uint32)t->next_mem ){
      dprintf(("memory block(%ld) size and next are inconsistent\n", (long)t->data[0] ));
      result = 0;
   } /* if */
#if 0
//   if( t->next_mem != NULL && t->next_mem->prev_mem != t) {
//      dprintf(("memory block(%ld) next doesn't link back\n", (long)t->data[0] ));
//   } /* if */
//   if( t->prev_mem != NULL && t->next_mem->prev_mem != t) {
//      dprintf(("memory block(%ld) prev doesn't link back\n", (long)t->data[0] ));
//   } /* if */
#endif
   if( ISDATA(t) ) {
      if( t->next_list == NULL && t != tail_data ) {
         dprintf(("memory block(%ld) is at end of data list, but doesn't match tail_data\n", (long)t->data[0] ));
         result = 0;
      } /* if */
      if( t->prev_list == NULL && t != head_data ) {
         dprintf(("memory block(%ld) is at head of data list, but doesn't match head_data\n", (long)t->data[0] ));
         result = 0;
      } /* if */
      if( *t->pbase == NULL ) {
         dprintf(("memory block(%ld) contains data, but *pbase is NULL\n", (long)t->data[0] ));
         result = 0;
      } /* if */
   }
   else {
      if( (t->next_mem != NULL) && ISFREE(t->next_mem) ) {
         dprintf(("memory block(%ld) is free and so is next block\n", (long)t->data[0] ));
         result = 0;
      } /* if */
      if( (t->prev_mem != NULL) && ISFREE(t->prev_mem) ) {
         dprintf(("memory block(%ld) is free and so is prev block\n", (long)t->data[0] ));
         result = 0;
      } /* if */
      if( (t->prev_list != NULL) && (t->size > t->prev_list->size) ) {
         dprintf(("memory block(%ld) is larger than next in free list\n", (long)t->data[0] ));
         result = 0;
      } /* if */
      if( (t->next_list != NULL) && (t->size < t->next_list->size) ) {
         dprintf(("memory block(%ld) is smaller than prev in free list\n", (long)t->data[0] ));
         result = 0;
      } /* if */
   } /* if */
   return result;
} /* check_block() */
Esempio n. 15
0
int _RTLENTRY _EXPFUNC _heapchk(void)
{
    int rc;
    HEAP *h;
    BLOCKHDR *bh;
    int fnum1 = 0;
    int fnum2 = 0;
    int commitSum = 0;

    int _roverFound = 0;

    _lock_heap();

    if (!_firstHeap)
        RETURN(_HEAPEMPTY);

    for (h = _firstHeap; h; h = h->nextHeap)
    {
        if (__memBogusAddr (h))
        {
            RETURN(_HEAPCORRUPT);
        }
        commitSum += h->cSize;
        for (bh = FIRSTBLOCK(h); HDR2PTR(bh) != ((char *) h + h->cSize); bh = NEXT(bh))
        {
            void *p = HDR2PTR(bh);

            if (__memBogusAddr (bh))
            {
                RETURN(_HEAPCORRUPT);
            }

            if (p < h || p > (char *) h + h->cSize)
            {
#ifdef DBG
                char buf[80];
                wsprintf(buf, "Block out of range block[%08X]  heap[%08X]", p, h);
                DBG_MAC (buf);
#endif
                RETURN(_HEAPCORRUPT);
            }

            if (ISFREE(bh))
            {
                if (__memBogusAddr(NEXT(bh)))
                {
                    RETURN(_HEAPCORRUPT);
                }
                if (!ISPFREE(NEXT(bh)))
                {
#ifdef DBG
                    DBG_MAC("prev free bit missing");
#endif
                    RETURN(_HEAPCORRUPT);
                }

                if (PFREE(NEXT(bh)) != bh)
                {
#ifdef DBG
                    DBG_MAC("free backlink broken");
#endif
                    RETURN(_HEAPCORRUPT);
                }

                fnum1++;
            }
        }
    }
    if (commitSum != __allocated)
    {
#ifdef DBG
        DBG_MAC("allocated number is off!!!");
#endif
        RETURN(_HEAPCORRUPT);
    }

    if (_linktable)
    {
        size_t i;

        for (i = MINSIZE; i < _smalloc_threshold; i += ALIGNMENT)
        {
            BLOCKHDR *p = HDR4SIZE(i);
            if (__memBogusAddr(p))
            {
                RETURN(_HEAPCORRUPT);
            }

            for (bh = p->nextFree; bh != p; bh = bh->nextFree)
            {
                if (__memBogusAddr(bh))
                {
                    RETURN(_HEAPCORRUPT);
                }
                if (__memBogusAddr(bh->nextFree))
                {
                    RETURN(_HEAPCORRUPT);
                }
                if (bh->nextFree->prevFree != bh)
                {
#ifdef DBG
                    DBG_MAC("free list error");
#endif
                    RETURN(_HEAPCORRUPT);
                }
                if (SIZE(bh) != i)
                {
#ifdef DBG
                    DBG_MAC("bad size block in small free list");
#endif
                    RETURN(_HEAPCORRUPT);
                }

                if (!ISPFREE(NEXT(bh)))
                {
#ifdef DBG
                    DBG_MAC("bad block in free list");
#endif
                    RETURN(_HEAPCORRUPT);
                }

                if (PFREE(NEXT(bh)) != bh)
                {
#ifdef DBG
                    DBG_MAC("bad block in free list");
#endif
                    RETURN(_HEAPCORRUPT);
                }

                fnum2++;
            }
        }

        for (bh = _freeStart.nextFree; bh != &_freeStart; bh = bh->nextFree)
        {
            if (__memBogusAddr(bh))
            {
                RETURN(_HEAPCORRUPT);
            }
            if (__memBogusAddr(bh->nextFree))
            {
                RETURN(_HEAPCORRUPT);
            }

            if (bh->nextFree->prevFree != bh)
            {
#ifdef DBG
                DBG_MAC("free list error");
#endif
                RETURN(_HEAPCORRUPT);
            }

            if (SIZE(bh) < _smalloc_threshold)
            {
#ifdef DBG
                DBG_MAC("small block in big free list");
#endif
                RETURN(_HEAPCORRUPT);
            }

            if (!ISPFREE(NEXT(bh)))
            {
#ifdef DBG
                DBG_MAC("bad block in free list");
#endif
                RETURN(_HEAPCORRUPT);
            }

            if (PFREE(NEXT(bh)) != bh)
            {
#ifdef DBG
                DBG_MAC("bad block in free list");
#endif
                RETURN(_HEAPCORRUPT);
            }

            fnum2++;

            if (bh == _rover)
                _roverFound = 1;
        }
    }

    if (!_roverFound && &_freeStart != _rover)
    {
#ifdef DBG
        DBG_MAC("_rover not in free list!");
#endif
        RETURN(_HEAPCORRUPT);
    }

    if (fnum1 != fnum2)
    {
#ifdef DBG
        DBG_MAC("Free block number mismatch");
#endif
        RETURN(_HEAPCORRUPT);
    }

    rc = _HEAPOK;
  exit:
    _unlock_heap();
    return rc;
}