summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_zone.h
blob: 8fe91d1e1aaf07ec06155d5cafc2700899e41a3d (plain)
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.h,v 1.11 1999/01/08 17:31:30 eivind Exp $
 */

#ifndef _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;

#ifdef INVARIANTS
	if (z == 0)
		zerror(ZONE_ERROR_INVALID);
#endif

	if (z->zfreecnt <= z->zfreemin)
		return _zget(z);

	item = z->zitems;
	z->zitems = ((void **) item)[0];
#ifdef INVARIANTS
	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;
#ifdef INVARIANTS
	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)
{
#ifdef SMP
	zfreei(z, item);
#else
	_zfree(z, item);
#endif
}

#endif
OpenPOWER on IntegriCloud