unix/MemorySupport.cpp
Go to the documentation of this file.
1 /*----------------------------------------------------------------------------*/
2 /* */
3 /* Copyright (c) 1995, 2004 IBM Corporation. All rights reserved. */
4 /* Copyright (c) 2005-2009 Rexx Language Association. All rights reserved. */
5 /* */
6 /* This program and the accompanying materials are made available under */
7 /* the terms of the Common Public License v1.0 which accompanies this */
8 /* distribution. A copy is also available at the following address: */
9 /* http://www.oorexx.org/license.html */
10 /* */
11 /* Redistribution and use in source and binary forms, with or */
12 /* without modification, are permitted provided that the following */
13 /* conditions are met: */
14 /* */
15 /* Redistributions of source code must retain the above copyright */
16 /* notice, this list of conditions and the following disclaimer. */
17 /* Redistributions in binary form must reproduce the above copyright */
18 /* notice, this list of conditions and the following disclaimer in */
19 /* the documentation and/or other materials provided with the distribution. */
20 /* */
21 /* Neither the name of Rexx Language Association nor the names */
22 /* of its contributors may be used to endorse or promote products */
23 /* derived from this software without specific prior written permission. */
24 /* */
25 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
26 /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
27 /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
28 /* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
29 /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
30 /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */
31 /* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */
32 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */
33 /* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
34 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
35 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
36 /* */
37 /*----------------------------------------------------------------------------*/
38 /******************************************************************************/
39 /* REXX AIX Support aixmem.c */
40 /* */
41 /* AIX memory management routines */
42 /* */
43 /******************************************************************************/
44 
45 
46 #include <stdlib.h>
47 #include "RexxCore.h"
48 #include "RexxMemory.hpp"
49 #include "ActivityManager.hpp"
50 #include "SystemInterpreter.hpp"
51 
52 #define MEMSIZE 4194304 /* memory pool */
53 #define PAGESIZE 4096 /* page size */
54 
55 /*********************************************************************/
56 /* */
57 /* Function: Allocate a block of memory suitable to pass back to */
58 /* another program as a return result */
59 /* */
60 /*********************************************************************/
62  size_t Size ) /* size to allocate */
63 {
64  return malloc(Size);
65 }
66 
67 /*********************************************************************/
68 /* */
69 /* Function: Release a block of memory given to us by an outside */
70 /* agent as a return result */
71 /* */
72 /*********************************************************************/
74  void *MemoryBlock) /* pointer to the result memory */
75 {
76  free(MemoryBlock); /* release this block */
77 }
78 
79 
81 /*********************************************************************/
82 /* Function: Access/Create the 1st block as Named Storage */
83 /* return true is an access, false is created. */
84 /*********************************************************************/
85 {
86  MemorySegmentPool * newPool;
87  void *tmpPtr;
88  size_t segmentSize;
89  /* create the shared memory segemnt */
90  /* if already exists then this */
91  /* isn't a coldstart. */
92  tmpPtr = (void *)calloc(MEMSIZE,1);
93  if (tmpPtr == NULL) /* Error on commit? */
94  {
96  }
97 
98  newPool = (MemorySegmentPool *)tmpPtr;
99  segmentSize = RXROUNDUP(SegmentSize, PAGESIZE);
100 
101  /* Since memory may not be ready */
102  /* for a segment we keep it as a spar*/
103  /* and will give it to memory on */
104  /* 1st request for a new segment. */
105 
106  newPool->spareSegment = new (((char *)newPool) + MemorySegmentPoolOverhead) MemorySegment (segmentSize - MemorySegmentPoolOverhead);
107  /* compute actual usable space. */
108  newPool->uncommitted = MEMSIZE - segmentSize;
109 #ifdef _DEBUG
110  newPool->reserved = MEMSIZE;
111 #endif
112  /* compute starting poin of next */
113  /* allocation. */
114  newPool->nextAlloc = (char *)newPool + segmentSize;
115 
116  /* start allocating large segments */
117  /* from the end of the pool. */
118  newPool->nextLargeAlloc = ((char*) newPool) + MEMSIZE;
119 
120  new (newPool) MemorySegmentPool; /* Initialize as a segmentPool */
121  return newPool; /* newly created. */
122 }
123 
124 void *MemorySegmentPool::operator new(size_t size, size_t minSize)
125 /*********************************************************************/
126 /* Function:: Create a new MemoryPool block */
127 /* */
128 /*********************************************************************/
129 {
130  MemorySegmentPool *newPool;
131  void *tmpPtr;
132  size_t initialSegSize;
133  size_t poolSize;
134 
135  /* Add pool object overhead to minSiz*/
136  minSize += MemorySegmentPoolOverhead;
137  if (minSize > MEMSIZE) /* Asking for more than default pool */
138  /* compute actual request size. */
139  poolSize = RXROUNDUP(minSize + MemorySegmentPoolOverhead, PAGESIZE);
140  else
141  poolSize = MEMSIZE;
142 
143 
144  tmpPtr = calloc(poolSize,1);
145  if (!tmpPtr) /* Error on commit? */
146  {
148  }
149 
150  newPool = (MemorySegmentPool *) tmpPtr;
151 
152  if (minSize < SegmentSize)
153  initialSegSize = RXROUNDUP(SegmentSize, PAGESIZE);
154  else
155  initialSegSize = RXROUNDUP(minSize, PAGESIZE);
156 
157  newPool->spareSegment = new (((char *)newPool) + MemorySegmentPoolOverhead) MemorySegment (initialSegSize - MemorySegmentPoolOverhead);
158  newPool->uncommitted = poolSize - initialSegSize;
159 #ifdef _DEBUG
160  newPool->reserved = poolSize;
161 #endif
162 
163  newPool->nextAlloc = (char *)newPool + initialSegSize;
164 
165  /* start allocating large segments */
166  /* from the end of the pool. */
167  newPool->nextLargeAlloc = ((char*) newPool) + poolSize;
168 
169  return newPool;
170 }
171 
173 /*********************************************************************/
174 /* Function:: Constructor for memoryPool block. */
175 /* set next to NULL, size to size, */
176 /* */
177 /*********************************************************************/
178 {
179  this->next = NULL; /* No next pointer right now */
180 }
181 
183 /*********************************************************************/
184 /* Function:: Constructor for memoryPool block. */
185 /* set next to NULL, size to size, */
186 /* */
187 /*********************************************************************/
188 {
189  size_t segmentSize;
190  MemorySegment *newSeg;
191  MemorySegmentPool *newPool;
192  /* Any spare segments left over */
193  /* from initial pool alloc? */
194  /* And big enough for this request? */
195  if (this->spareSegment && this->spareSegment->size() >= minSize)
196  {
197  newSeg = this->spareSegment; /* no longer have a spare */
198  this->spareSegment = NULL;
199  return newSeg; /* return this segment for allocation*/
200  }
201  segmentSize = RXROUNDUP(minSize, PAGESIZE); /* compute commit size */
202  /* enough space for request */
203  if (this->uncommitted >= segmentSize)
204  {
205  newSeg = new (this->nextAlloc) MemorySegment (segmentSize);
206 
207  this->uncommitted -= segmentSize; /* Adjust uncommitted amount */
208  this->nextAlloc += segmentSize; /* Adjust to next Allocation addr */
209  return newSeg;
210  }
211  else /* uncommitted not enough need a new pool */
212  {
213  newPool = new (minSize) MemorySegmentPool;
214  if (newPool)
215  { /* Did we get a new Pool? */
216  this->next = newPool; /* Anchor it to end of chain */
217  memoryObject.memoryPoolAdded(newPool); // tell the memory object we'v added a new pool
218  return newPool->newSegment(minSize);
219  }
220  else
221  {
222  return NULL;
223  }
224  }
225 }
226 
228 /*********************************************************************/
229 /* Function: Allocate a large segment from the other end of the pool */
230 /*********************************************************************/
231 {
232  size_t segmentSize;
233  MemorySegment *newSeg;
234  MemorySegmentPool *newPool;
235 
236  /* Any spare segments left over */
237  /* from initial pool alloc? */
238  /* And big enough for this request? */
239  if (this->spareSegment && this->spareSegment->size() >= minSize)
240  {
241  newSeg = this->spareSegment; /* no longer have a spare */
242  this->spareSegment = NULL;
243  return newSeg; /* return this segment for allocation*/
244  }
245 
246  /* compute commit size */
247  segmentSize = RXROUNDUP(minSize, PAGESIZE);
248  /* enough space for request */
249  if (this->uncommitted >= segmentSize)
250  {
251  this->nextLargeAlloc = this->nextLargeAlloc - segmentSize; // already calloc'd on AIX, just move pointer
252 
253  /* Create new segment. */
254  newSeg = new (this->nextLargeAlloc) MemorySegment (segmentSize);
255  this->uncommitted -= segmentSize; /* Adjust uncommitted amount */
256  // this->nextLargeAlloc does not have to be adjusted, will be correct
257  return newSeg;
258  }
259  else
260  {
261  newPool = new (minSize) MemorySegmentPool;
262  if (newPool) /* Did we get a new Pool? */
263  {
264  /* Make sure new pool is added to the end of list */
265  this->next = newPool; /* Anchor it to end of chain */
266  memoryObject.memoryPoolAdded(newPool); // tell the memory object we've added a new pool
267  return newPool->newLargeSegment(minSize);
268  }
269  else
270  {
271  return NULL;
272  }
273  }
274 }
275 
276 void MemorySegmentPool::freePool() // add return value
277 /*********************************************************************/
278 /* Function:: Free this pool object */
279 /*********************************************************************/
280 {
281  free(this);
282 }
283 
284 /******************** added by weigold *******************************/
286 /*********************************************************************/
287 /* Function:: set the next pointer */
288 /*********************************************************************/
289 {
290  this->next = nextPoolPtr;
291 }
void reportException(wholenumber_t error)
#define SegmentSize
#define MemorySegmentPoolOverhead
#define RXROUNDUP(n, to)
Definition: RexxCore.h:221
#define Error_System_resources
RexxMemory memoryObject
Definition: RexxMemory.cpp:86
MemorySegment * spareSegment
Definition: RexxMemory.hpp:133
MemorySegmentPool * next
Definition: RexxMemory.hpp:132
MemorySegment * newLargeSegment(size_t minSize)
MemorySegment * newSegment(size_t minSize)
static MemorySegmentPool * createPool()
void setNext(MemorySegmentPool *nextPool)
void memoryPoolAdded(MemorySegmentPool *)
static void * allocateResultMemory(size_t)
static void releaseResultMemory(void *)
#define PAGESIZE
#define MEMSIZE