summaryrefslogtreecommitdiffstats
path: root/private/crt32/winheap/expand.c
blob: 8b142e19457c37331075512bcfcdecaf7b95aec5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
/***
*expand.c - Win32 expand heap routine
*
*	Copyright (c) 1991-1992, Microsoft Corporation.  All rights reserved.
*
*Purpose:
*
*Revision History:
*	01-15-92  JCR	Module created.
*	02-04-92  GJF	Replaced windows.h with oscalls.h.
*	05-06-92  DJM	ifndef out of POSIX build.
*	09-23-92  SRW	Change winheap code to call NT directly always
*	10-15-92  SKS	Removed the ill-named HEAP_GROWTH_ALLOWED flag
*			which was causing a bug: _expand was behaving like
*			realloc(), by moving the block when it could not be
*			grown in place.  _expand() must NEVER move the block.
*			Also added a safety check to work around a bug in
*			HeapReAlloc, where it returns success even
*			when it fails to grow the block in place.
*	10-28-92  SRW	Change winheap code to call Heap????Ex calls
*	11-05-92  SKS	Change name of variable "CrtHeap" to "_crtheap"
*	11-07-92  SRW   _NTIDW340 replaced by linkopts\betacmp.c
*	11-16-92  SRW   Heap???Ex functions renamed to Heap???
*
*******************************************************************************/

#ifndef _POSIX_

#include <cruntime.h>
#include <malloc.h>
#include <winheap.h>
#include <oscalls.h>

/***
*void *_expand(void *pblck, size_t newsize) - expand/contract a block of memory
*	in the heap
*
*Purpose:
*	Resizes a block in the heap to newsize bytes. newsize may be either
*	greater (expansion) or less (contraction) than the original size of
*	the block. The block is NOT moved.
*
*	NOTES:
*
*	(1) In this implementation, if the block cannot be grown to the
*	desired size, the resulting block will NOT be grown to the max
*	possible size.	(That is, either it works or it doesn't.)
*
*	(2) Unlike other implementations, you can NOT pass a previously
*	freed block to this routine and expect it to work.
*
*Entry:
*	void *pblck	- pointer to block in the heap previously allocated
*			  by a call to malloc(), realloc() or _expand().
*
*	size_t newsize	- requested size for the resized block
*
*Exit:
*	Success:  Pointer to the resized memory block (i.e., pblck)
*	Failure:  NULL
*
*Uses:
*
*Exceptions:
*	If pblck does not point to a valid allocation block in the heap,
*	_expand() will behave unpredictably and probably corrupt the heap.
*
*******************************************************************************/

void * _CALLTYPE1 _expand(pblock, n)
void * pblock;
size_t	n;

{
  void * p;

  p = HeapReAlloc(_crtheap,
                  HEAP_REALLOC_IN_PLACE_ONLY,
                  pblock,
                  n ? n : 1
                 );

  /**
   * Temporary BUG work-around:
   *	HeapReAlloc sometimes (often?) returns success
   *	even when there has been a failure to grow in place.
   *	This conditional will recognize this case and handle it.
  **/
  return ( p == pblock ) && ( _msize(pblock) >= n ) ? pblock : NULL;
}

#endif  /* !_POSIX_ */