1 /***********************************************************************
3 * This software is part of the ast package *
4 * Copyright (c) 1985-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
13 * Information and Software Systems Research *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
21 ***********************************************************************/
22 #if defined(_UWIN) && defined(_BLD_ast)
30 /* Opening a new region of allocation.
31 ** Note that because of possible exotic memory types,
32 ** all region data must be stored within the space given
35 ** Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/94.
38 typedef struct _vminit_
40 Vmdata_t vd
; /* space for the region itself */
41 Seg_t seg
; /* space for segment */
42 Block_t block
; /* space for a block */
43 Head_t head
; /* space for the fake header */
44 char a
[3*ALIGN
]; /* extra to fuss with alignment */
48 Vmalloc_t
* vmopen(Vmdisc_t
* disc
, Vmethod_t
* meth
, int mode
)
50 Vmalloc_t
* vmopen(disc
, meth
, mode
)
51 Vmdisc_t
* disc
; /* discipline to get segments */
52 Vmethod_t
* meth
; /* method to manage space */
53 int mode
; /* type of region */
58 reg
size_t s
, a
, incr
;
62 reg Vmemory_f memoryf
;
65 if(!meth
|| !disc
|| !(memoryf
= disc
->memoryf
) )
66 return NIL(Vmalloc_t
*);
68 GETPAGESIZE(_Vmpagesize
);
70 /* note that Vmalloc_t space must be local to process since that's
71 where the meth&disc function addresses are going to be stored */
72 if(!(vm
= (Vmalloc_t
*)vmalloc(Vmheap
,sizeof(Vmalloc_t
))) )
73 return NIL(Vmalloc_t
*);
76 vm
->file
= NIL(char*);
80 { addr
= NIL(Vmuchar_t
*);
81 if((e
= (*disc
->exceptf
)(vm
,VM_OPEN
,(Void_t
*)(&addr
),disc
)) != 0)
85 /* align this address */
86 if((a
= (size_t)(VLONG(addr
)%ALIGN
)) != 0)
89 /* see if it's a valid region */
91 if((vd
->mode
&meth
->meth
) != 0)
98 return NIL(Vmalloc_t
*);
103 /* make sure vd->incr is properly rounded */
104 incr
= disc
->round
<= 0 ? _Vmpagesize
: disc
->round
;
105 incr
= MULTIPLE(incr
,ALIGN
);
107 /* get space for region data */
108 s
= ROUND(sizeof(Vminit_t
),incr
);
109 if(!(addr
= (Vmuchar_t
*)(*memoryf
)(vm
,NIL(Void_t
*),0,s
,disc
)) )
111 return NIL(Vmalloc_t
*);
114 /* make sure that addr is aligned */
115 if((a
= (size_t)(VLONG(addr
)%ALIGN
)) != 0)
118 /* initialize region */
119 vd
= (Vmdata_t
*)addr
;
120 vd
->mode
= (mode
&VM_FLAGS
) | meth
->meth
;
123 vd
->free
= vd
->wild
= NIL(Block_t
*);
125 if(vd
->mode
&(VM_TRACE
|VM_MTDEBUG
))
126 vd
->mode
&= ~VM_TRUST
;
128 if(vd
->mode
&(VM_MTBEST
|VM_MTDEBUG
|VM_MTPROFILE
))
129 { vd
->root
= NIL(Block_t
*);
130 for(e
= S_TINY
-1; e
>= 0; --e
)
131 TINY(vd
)[e
] = NIL(Block_t
*);
132 for(e
= S_CACHE
; e
>= 0; --e
)
133 CACHE(vd
)[e
] = NIL(Block_t
*);
134 incr
= sizeof(Vmdata_t
);
136 else incr
= OFFSET(Vmdata_t
,root
);
138 vd
->seg
= (Seg_t
*)(addr
+ ROUND(incr
,ALIGN
));
139 /**/ ASSERT(VLONG(vd
->seg
)%ALIGN
== 0);
142 seg
->next
= NIL(Seg_t
*);
144 seg
->addr
= (Void_t
*)(addr
- (a
? ALIGN
-a
: 0));
146 seg
->baddr
= addr
+ s
- (a
? ALIGN
: 0);
147 seg
->size
= s
; /* this size is larger than usual so that the segment
148 will not be freed until the region is closed. */
149 seg
->free
= NIL(Block_t
*);
151 /* make a data block out of the remainder */
154 SIZE(b
) = seg
->baddr
- (Vmuchar_t
*)b
- 2*sizeof(Head_t
);
156 /**/ ASSERT(SIZE(b
)%ALIGN
== 0);
157 /**/ ASSERT(VLONG(b
)%ALIGN
== 0);
159 /* make a fake header for next block in case of noncontiguous segments */
161 SIZE(NEXT(b
)) = BUSY
|PFREE
;
163 if(vd
->mode
&(VM_MTLAST
|VM_MTPOOL
))
169 done
: /* add to the linked list of regions */
170 vm
->next
= Vmheap
->next
;