1da2e3ebdSchin /***********************************************************************
2da2e3ebdSchin * *
3da2e3ebdSchin * This software is part of the ast package *
4*3e14f97fSRoger A. Faulkner * Copyright (c) 1985-2010 AT&T Intellectual Property *
5da2e3ebdSchin * and is licensed under the *
6da2e3ebdSchin * Common Public License, Version 1.0 *
77c2fbfb3SApril Chin * by AT&T Intellectual Property *
8da2e3ebdSchin * *
9da2e3ebdSchin * A copy of the License is available at *
10da2e3ebdSchin * http://www.opensource.org/licenses/cpl1.0.txt *
11da2e3ebdSchin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
12da2e3ebdSchin * *
13da2e3ebdSchin * Information and Software Systems Research *
14da2e3ebdSchin * AT&T Research *
15da2e3ebdSchin * Florham Park NJ *
16da2e3ebdSchin * *
17da2e3ebdSchin * Glenn Fowler <gsf@research.att.com> *
18da2e3ebdSchin * David Korn <dgk@research.att.com> *
19da2e3ebdSchin * Phong Vo <kpv@research.att.com> *
20da2e3ebdSchin * *
21da2e3ebdSchin ***********************************************************************/
22da2e3ebdSchin #if defined(_UWIN) && defined(_BLD_ast)
23da2e3ebdSchin
_STUB_vmopen()24da2e3ebdSchin void _STUB_vmopen(){}
25da2e3ebdSchin
26da2e3ebdSchin #else
27da2e3ebdSchin
28da2e3ebdSchin #include "vmhdr.h"
29da2e3ebdSchin
30da2e3ebdSchin /* Opening a new region of allocation.
31da2e3ebdSchin ** Note that because of possible exotic memory types,
32da2e3ebdSchin ** all region data must be stored within the space given
33da2e3ebdSchin ** by the discipline.
34da2e3ebdSchin **
35da2e3ebdSchin ** Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/94.
36da2e3ebdSchin */
37da2e3ebdSchin
38da2e3ebdSchin typedef struct _vminit_
39da2e3ebdSchin {
40da2e3ebdSchin Vmdata_t vd; /* space for the region itself */
41da2e3ebdSchin Seg_t seg; /* space for segment */
42da2e3ebdSchin Block_t block; /* space for a block */
43da2e3ebdSchin Head_t head; /* space for the fake header */
44da2e3ebdSchin char a[3*ALIGN]; /* extra to fuss with alignment */
45da2e3ebdSchin } Vminit_t;
46da2e3ebdSchin
47da2e3ebdSchin #if __STD_C
vmopen(Vmdisc_t * disc,Vmethod_t * meth,int mode)48da2e3ebdSchin Vmalloc_t* vmopen(Vmdisc_t* disc, Vmethod_t* meth, int mode)
49da2e3ebdSchin #else
50da2e3ebdSchin Vmalloc_t* vmopen(disc, meth, mode)
51da2e3ebdSchin Vmdisc_t* disc; /* discipline to get segments */
52da2e3ebdSchin Vmethod_t* meth; /* method to manage space */
53da2e3ebdSchin int mode; /* type of region */
54da2e3ebdSchin #endif
55da2e3ebdSchin {
56da2e3ebdSchin reg Vmalloc_t* vm;
57da2e3ebdSchin reg Vmdata_t* vd;
58da2e3ebdSchin reg size_t s, a, incr;
59da2e3ebdSchin reg Block_t* b;
60da2e3ebdSchin reg Seg_t* seg;
61da2e3ebdSchin Vmuchar_t* addr;
62da2e3ebdSchin reg Vmemory_f memoryf;
63da2e3ebdSchin reg int e;
64da2e3ebdSchin
65da2e3ebdSchin if(!meth || !disc || !(memoryf = disc->memoryf) )
66da2e3ebdSchin return NIL(Vmalloc_t*);
67da2e3ebdSchin
68da2e3ebdSchin GETPAGESIZE(_Vmpagesize);
69da2e3ebdSchin
70da2e3ebdSchin /* note that Vmalloc_t space must be local to process since that's
71da2e3ebdSchin where the meth&disc function addresses are going to be stored */
72da2e3ebdSchin if(!(vm = (Vmalloc_t*)vmalloc(Vmheap,sizeof(Vmalloc_t))) )
73da2e3ebdSchin return NIL(Vmalloc_t*);
74da2e3ebdSchin vm->meth = *meth;
75da2e3ebdSchin vm->disc = disc;
76da2e3ebdSchin vm->file = NIL(char*);
77da2e3ebdSchin vm->line = 0;
78da2e3ebdSchin
79da2e3ebdSchin if(disc->exceptf)
80da2e3ebdSchin { addr = NIL(Vmuchar_t*);
81da2e3ebdSchin if((e = (*disc->exceptf)(vm,VM_OPEN,(Void_t*)(&addr),disc)) != 0)
82da2e3ebdSchin { if(e < 0 || !addr)
83da2e3ebdSchin goto open_error;
84da2e3ebdSchin
85da2e3ebdSchin /* align this address */
86da2e3ebdSchin if((a = (size_t)(VLONG(addr)%ALIGN)) != 0)
87da2e3ebdSchin addr += ALIGN-a;
88da2e3ebdSchin
89da2e3ebdSchin /* see if it's a valid region */
90da2e3ebdSchin vd = (Vmdata_t*)addr;
91da2e3ebdSchin if((vd->mode&meth->meth) != 0)
92da2e3ebdSchin { vm->data = vd;
93*3e14f97fSRoger A. Faulkner goto done;
94da2e3ebdSchin }
95da2e3ebdSchin else
96da2e3ebdSchin { open_error:
97da2e3ebdSchin vmfree(Vmheap,vm);
98da2e3ebdSchin return NIL(Vmalloc_t*);
99da2e3ebdSchin }
100da2e3ebdSchin }
101da2e3ebdSchin }
102da2e3ebdSchin
103da2e3ebdSchin /* make sure vd->incr is properly rounded */
104da2e3ebdSchin incr = disc->round <= 0 ? _Vmpagesize : disc->round;
105da2e3ebdSchin incr = MULTIPLE(incr,ALIGN);
106da2e3ebdSchin
107da2e3ebdSchin /* get space for region data */
108da2e3ebdSchin s = ROUND(sizeof(Vminit_t),incr);
109da2e3ebdSchin if(!(addr = (Vmuchar_t*)(*memoryf)(vm,NIL(Void_t*),0,s,disc)) )
110da2e3ebdSchin { vmfree(Vmheap,vm);
111da2e3ebdSchin return NIL(Vmalloc_t*);
112da2e3ebdSchin }
113da2e3ebdSchin
114da2e3ebdSchin /* make sure that addr is aligned */
115da2e3ebdSchin if((a = (size_t)(VLONG(addr)%ALIGN)) != 0)
116da2e3ebdSchin addr += ALIGN-a;
117da2e3ebdSchin
118da2e3ebdSchin /* initialize region */
119da2e3ebdSchin vd = (Vmdata_t*)addr;
120da2e3ebdSchin vd->mode = (mode&VM_FLAGS) | meth->meth;
121da2e3ebdSchin vd->incr = incr;
122da2e3ebdSchin vd->pool = 0;
123da2e3ebdSchin vd->free = vd->wild = NIL(Block_t*);
124da2e3ebdSchin
125da2e3ebdSchin if(vd->mode&(VM_TRACE|VM_MTDEBUG))
126da2e3ebdSchin vd->mode &= ~VM_TRUST;
127da2e3ebdSchin
128da2e3ebdSchin if(vd->mode&(VM_MTBEST|VM_MTDEBUG|VM_MTPROFILE))
129da2e3ebdSchin { vd->root = NIL(Block_t*);
130da2e3ebdSchin for(e = S_TINY-1; e >= 0; --e)
131da2e3ebdSchin TINY(vd)[e] = NIL(Block_t*);
132da2e3ebdSchin for(e = S_CACHE; e >= 0; --e)
133da2e3ebdSchin CACHE(vd)[e] = NIL(Block_t*);
134da2e3ebdSchin incr = sizeof(Vmdata_t);
135da2e3ebdSchin }
136da2e3ebdSchin else incr = OFFSET(Vmdata_t,root);
137da2e3ebdSchin
138da2e3ebdSchin vd->seg = (Seg_t*)(addr + ROUND(incr,ALIGN));
139da2e3ebdSchin /**/ ASSERT(VLONG(vd->seg)%ALIGN == 0);
140da2e3ebdSchin
141da2e3ebdSchin seg = vd->seg;
142da2e3ebdSchin seg->next = NIL(Seg_t*);
143*3e14f97fSRoger A. Faulkner seg->vmdt = vd;
144da2e3ebdSchin seg->addr = (Void_t*)(addr - (a ? ALIGN-a : 0));
145da2e3ebdSchin seg->extent = s;
146da2e3ebdSchin seg->baddr = addr + s - (a ? ALIGN : 0);
147da2e3ebdSchin seg->size = s; /* this size is larger than usual so that the segment
148da2e3ebdSchin will not be freed until the region is closed. */
149da2e3ebdSchin seg->free = NIL(Block_t*);
150da2e3ebdSchin
151da2e3ebdSchin /* make a data block out of the remainder */
152da2e3ebdSchin b = SEGBLOCK(seg);
153da2e3ebdSchin SEG(b) = seg;
154da2e3ebdSchin SIZE(b) = seg->baddr - (Vmuchar_t*)b - 2*sizeof(Head_t);
155da2e3ebdSchin *SELF(b) = b;
156da2e3ebdSchin /**/ ASSERT(SIZE(b)%ALIGN == 0);
157da2e3ebdSchin /**/ ASSERT(VLONG(b)%ALIGN == 0);
158da2e3ebdSchin
159da2e3ebdSchin /* make a fake header for next block in case of noncontiguous segments */
160da2e3ebdSchin SEG(NEXT(b)) = seg;
161da2e3ebdSchin SIZE(NEXT(b)) = BUSY|PFREE;
162da2e3ebdSchin
163da2e3ebdSchin if(vd->mode&(VM_MTLAST|VM_MTPOOL))
164da2e3ebdSchin seg->free = b;
165da2e3ebdSchin else vd->wild = b;
166da2e3ebdSchin
167da2e3ebdSchin vm->data = vd;
168da2e3ebdSchin
169*3e14f97fSRoger A. Faulkner done: /* add to the linked list of regions */
170da2e3ebdSchin vm->next = Vmheap->next;
171da2e3ebdSchin Vmheap->next = vm;
172da2e3ebdSchin
173da2e3ebdSchin return vm;
174da2e3ebdSchin }
175da2e3ebdSchin
176da2e3ebdSchin #endif
177