Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /****************************************************************************
  2. *
  3. *                            Open Watcom Project
  4. *
  5. *    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
  6. *
  7. *  ========================================================================
  8. *
  9. *    This file contains Original Code and/or Modifications of Original
  10. *    Code as defined in and that are subject to the Sybase Open Watcom
  11. *    Public License version 1.0 (the 'License'). You may not use this file
  12. *    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
  13. *    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
  14. *    provided with the Original Code and Modifications, and is also
  15. *    available at www.sybase.com/developer/opensource.
  16. *
  17. *    The Original Code and all software distributed under the License are
  18. *    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  19. *    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
  20. *    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
  21. *    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
  22. *    NON-INFRINGEMENT. Please see the License for the specific language
  23. *    governing rights and limitations under the License.
  24. *
  25. *  ========================================================================
  26. *
  27. * Description:  Implementation of near _heapchk() and _nheapchk().
  28. *
  29. ****************************************************************************/
  30.  
  31.  
  32. //#include "dll.h"        // needs to be first
  33. #include "variety.h"
  34. #include <stddef.h>
  35. #include <malloc.h>
  36. #include "heap.h"
  37. #include "heapacc.h"
  38.  
  39. frlptr __nheapchk_current;
  40.  
  41. static int checkFreeList( size_t *free_size )
  42. {
  43.     frlptr p;
  44.     frlptr end;
  45.     size_t new_size;
  46.     size_t free_list_size = 0;
  47.     mheapptr mhp;
  48.  
  49.     for( mhp = __nheapbeg; mhp != NULL; mhp = mhp ->next ) {
  50.         /* check that the free list is a doubly linked ring */
  51.         __nheapchk_current = p = mhp->freehead.next;
  52.         /* make sure we start off on the right track */
  53.         if( (p->prev == NULL) ||
  54.             (p->prev < &(mhp->freehead)) ||
  55.             (((PTR)p->prev) > (((PTR)mhp)+mhp->len)) ) {
  56.             return( _HEAPBADNODE );
  57.         }
  58.         if( p->prev->next != p ) {
  59.             return( _HEAPBADNODE );
  60.         }
  61.         end = p;
  62.         do {
  63.             /* loop invariant: p->prev->next == p */
  64.             /* are we still in a ring if we move to p->next? */
  65.             /* nb. this check is sufficient to ensure that we will
  66.                never cycle              */
  67.             if( (p->next == NULL) ||
  68.                 (p->next < &(mhp->freehead)) ||
  69.                 (((PTR)p->next) > (((PTR)mhp)+mhp->len)) ) {
  70.                 return( _HEAPBADNODE );
  71.             }
  72.             if( p->next->prev != p ) {
  73.                 return( _HEAPBADNODE );
  74.             }
  75.             /* is entry allocated? */
  76.             if( p->len & 1 ) {
  77.                 return( _HEAPBADNODE );
  78.             }
  79.             new_size = free_list_size + p->len;
  80.             if( new_size < free_list_size ) {
  81.                 /* this is a case where we do not know where memory
  82.                    is corrupted         */
  83.                 return( _HEAPBADNODE );
  84.             }
  85.             free_list_size = new_size;
  86.             __nheapchk_current = p = p->next;
  87.         } while( p != end );
  88.     }
  89.     *free_size = free_list_size;
  90.     return( _HEAPOK );
  91. }
  92.  
  93. static int checkFree( frlptr p )
  94. {
  95.     frlptr next;
  96.     frlptr prev;
  97.     frlptr next_next;
  98.     frlptr prev_prev;
  99.  
  100.     __nheapchk_current = p;
  101.     if( p->len & 1 ) {
  102.         return( _HEAPBADNODE );
  103.     }
  104.     next = p->next;
  105.     prev = p->prev;
  106.     if( next->prev != p || prev->next != p ) {
  107.         return( _HEAPBADNODE );
  108.     }
  109.     next_next = next->next;
  110.     prev_prev = prev->prev;
  111.     if( next_next->prev != next || prev_prev->next != prev ) {
  112.         return( _HEAPBADNODE );
  113.     }
  114.     if( next_next->prev != next || prev_prev->next != prev ) {
  115.         return( _HEAPBADNODE );
  116.     }
  117.     return( _HEAPOK );
  118. }
  119.  
  120. #if defined(__SMALL_DATA__)
  121. _WCRTLINK int _heapchk( void )
  122. {
  123.     return( _nheapchk() );
  124. }
  125. #endif
  126.  
  127. _WCRTLINK int _nheapchk( void )
  128. {
  129.     struct _heapinfo hi;
  130.     int heap_status;
  131.     size_t free_size;
  132.  
  133.     _AccessNHeap();
  134.     heap_status = checkFreeList( &free_size );
  135.     if( heap_status != _HEAPOK ) {
  136.         _ReleaseNHeap();
  137.         return( heap_status );
  138.     }
  139.     hi._pentry = NULL;
  140.     for(;;) {
  141.         heap_status = __NHeapWalk( &hi, __nheapbeg );
  142.         if( heap_status != _HEAPOK )
  143.             break;
  144.         if( hi._useflag == _FREEENTRY ) {
  145.             heap_status = checkFree( (frlptr) hi._pentry );
  146.             if( heap_status != _HEAPOK )
  147.                 break;
  148.             free_size -= hi._size;
  149.         }
  150.     }
  151.     if( free_size != 0 ) {
  152.         heap_status = _HEAPBADNODE;
  153.     } else if( heap_status == _HEAPBADPTR ) {
  154.         heap_status = _HEAPBADNODE;
  155.     } else {
  156.         if( heap_status == _HEAPEND ) {
  157.             heap_status = _HEAPOK;
  158.         }
  159.     }
  160.     _ReleaseNHeap();
  161.     return( heap_status );
  162. }
  163.