Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
359 serge 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 
35
#include 
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
}