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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
/*
* Copyright (c) 1997, 1998 John S. Dyson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice immediately at the beginning of the file, without modification,
* this list of conditions, and the following disclaimer.
* 2. Absolutely no warranty of function or purpose is made by the author
* John S. Dyson.
*
* $Id: vm_zone.c,v 1.20 1998/04/15 17:47:40 bde Exp $
*/
#if !defined(_SYS_ZONE_H)
#define _SYS_ZONE_H
#define ZONE_INTERRUPT 1 /* Use this if you need to allocate at int time */
#define ZONE_BOOT 16 /* This is an internal flag used by zbootinit */
#include <machine/lock.h>
typedef struct vm_zone {
struct simplelock zlock; /* lock for data structure */
void *zitems; /* linked list of items */
int zfreecnt; /* free entries */
int zfreemin; /* minimum number of free entries */
int znalloc; /* number of allocations */
vm_offset_t zkva; /* Base kva of zone */
int zpagecount; /* Total # of allocated pages */
int zpagemax; /* Max address space */
int zmax; /* Max number of entries allocated */
int ztotal; /* Total entries allocated now */
int zsize; /* size of each entry */
int zalloc; /* hint for # of pages to alloc */
int zflags; /* flags for zone */
int zallocflag; /* flag for allocation */
struct vm_object *zobj; /* object to hold zone */
char *zname; /* name for diags */
struct vm_zone *znext; /* list of zones for sysctl */
} *vm_zone_t;
void zerror __P((int)) __dead2;
vm_zone_t zinit __P((char *name, int size, int nentries, int flags,
int zalloc));
int zinitna __P((vm_zone_t z, struct vm_object *obj, char *name,
int size, int nentries, int flags, int zalloc));
static void * zalloc __P((vm_zone_t z));
static void zfree __P((vm_zone_t z, void *item));
void * zalloci __P((vm_zone_t z));
void zfreei __P((vm_zone_t z, void *item));
void zbootinit __P((vm_zone_t z, char *name, int size, void *item,
int nitems));
void * _zget __P((vm_zone_t z));
#define ZONE_ERROR_INVALID 0
#define ZONE_ERROR_NOTFREE 1
#define ZONE_ERROR_ALREADYFREE 2
#define ZONE_ROUNDING 32
#define ZENTRY_FREE 0x12342378
/*
* void *zalloc(vm_zone_t zone) --
* Returns an item from a specified zone.
*
* void zfree(vm_zone_t zone, void *item) --
* Frees an item back to a specified zone.
*/
static __inline__ void *
_zalloc(vm_zone_t z)
{
void *item;
#if defined(DIAGNOSTIC)
if (z == 0)
zerror(ZONE_ERROR_INVALID);
#endif
if (z->zfreecnt <= z->zfreemin)
return _zget(z);
item = z->zitems;
z->zitems = ((void **) item)[0];
#if defined(DIAGNOSTIC)
if (((void **) item)[1] != (void *) ZENTRY_FREE)
zerror(ZONE_ERROR_NOTFREE);
((void **) item)[1] = 0;
#endif
z->zfreecnt--;
z->znalloc++;
return item;
}
static __inline__ void
_zfree(vm_zone_t z, void *item)
{
((void **) item)[0] = z->zitems;
#if defined(DIAGNOSTIC)
if (((void **) item)[1] == (void *) ZENTRY_FREE)
zerror(ZONE_ERROR_ALREADYFREE);
((void **) item)[1] = (void *) ZENTRY_FREE;
#endif
z->zitems = item;
z->zfreecnt++;
}
static __inline__ void *
zalloc(vm_zone_t z)
{
#if defined(SMP)
return zalloci(z);
#else
return _zalloc(z);
#endif
}
static __inline__ void
zfree(vm_zone_t z, void *item)
{
#if defined(SMP)
zfreei(z, item);
#else
_zfree(z, item);
#endif
}
#endif
|