1 /***********************************************************************
2 *                                                                      *
3 *               This software is part of the ast package               *
4 *          Copyright (c) 1999-2013 AT&T Intellectual Property          *
5 *                      and is licensed under the                       *
6 *                 Eclipse Public License, Version 1.0                  *
7 *                    by AT&T Intellectual Property                     *
8 *                                                                      *
9 *                A copy of the License is available at                 *
10 *          http://www.eclipse.org/org/documents/epl-v10.html           *
11 *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12 *                                                                      *
13 *              Information and Software Systems Research               *
14 *                            AT&T Research                             *
15 *                           Florham Park NJ                            *
16 *                                                                      *
17 *               Glenn Fowler <glenn.s.fowler@gmail.com>                *
18 *                                                                      *
19 ***********************************************************************/
20 #include	"vmtest.h"
21 
22 /* Test memory obtained by vmmopen.
23 **
24 ** Written by Kiem-Phong Vo
25 */
26 
27 #define M_SIZE	(4*1024) /* max size of a blk	*/
28 #define	N_ALLOC	(512)	/* #allocations 	*/
29 #define N_FREE	(256)	/* #frees <= #allocs	*/
30 
31 typedef struct _piece_s
32 {
33 	Void_t*	addr;	/* allocated address	*/
34 	size_t	size;	/* size to be allocated	*/
35 	int	free;	/* 1: to be freed	*/
36 } Piece_t;
37 Piece_t	Piece[N_ALLOC];
38 
working(char * store,int type,ssize_t size)39 static int working(char* store, int type, ssize_t size)
40 {
41 	ssize_t		k, f, nbusy, nfree;
42 	Vmdisc_t	*dc;
43 	Vmalloc_t	*vm;
44 	Vmstat_t	vmst;
45 
46 	tinfo("About to reopen region based on file %s", store);
47 
48 	if(!(dc = vmdcshare(store, type, size, 1)) ||
49 	   !(vm = vmopen(dc, Vmbest, 0)) )
50 		terror("Can't open region based on %s", store);
51 	tinfo("Region successfully opened", store);
52 	if(vmstat(vm, &vmst) < 0)
53 		terror("vmstat failed");
54 
55 	nbusy = nfree = 0;
56 	for(k = f = 0; k < N_ALLOC; ++k)
57 	{	if(!(Piece[k].addr = vmalloc(vm, Piece[k].size)) )
58 			terror("Vmalloc[k=%d,size=%d] failed ", k, Piece[k].size);
59 		nbusy += 1;
60 		if(k < (N_ALLOC-1) && (random()%100) != 0 )
61 			continue;
62 
63 		for(; f <= k; ++f ) /* free anything that should be freed */
64 		{	if(!Piece[f].free)
65 				continue;
66 			if(vmfree(vm, Piece[f].addr) < 0)
67 				terror("Vmfree [f=%d] failed", f);
68 			nfree += 1;
69 			nbusy -= 1;
70 			Piece[f].free = 0;
71 			Piece[f].addr = (Void_t*)0;
72 		}
73 	}
74 
75 	if(vmstat(vm, &vmst) < 0)
76 		terror("vmstat failed");
77 	tinfo("extent=%d busy=(expect=%d,actual=%d,z=%d) free=(n=%d,z=%d)",
78 		vmst.extent, nbusy, vmst.n_busy, vmst.s_busy, vmst.n_free, vmst.s_free);
79 	if(nbusy != vmst.n_busy)
80 		terror("Number of busy pieces is wrong nbusy=%d != vmst.n_busy=%d", nbusy, vmst.n_busy);
81 
82 	vmclose(vm);
83 
84 	return 0;
85 }
86 
tmain()87 tmain()
88 {
89 	ssize_t		k, f, size;
90 	Vmstat_t	vmst;
91 	Vmdisc_t	*dc;
92 	Vmalloc_t	*vm;
93 	char		*store;
94 
95 	size = 0; /* make up list of pieces for allocation */
96 	srandom(0); /* make it easier to debug */
97 	for(k = 0; k < N_ALLOC; ++k)
98 	{	Piece[k].size = (random()%M_SIZE) + 1;
99 		size += Piece[k].size + 32; /* add slop for malloc header */
100 	}
101 	for(f = 0; f < N_FREE; ) /* set up what should be freed */
102 	{	for(k = 0; k < N_ALLOC; ++k)
103 		{	if(Piece[k].free == 1)
104 				continue;
105 			else if(random()%(N_ALLOC/N_FREE) == 0)
106 			{	Piece[k].free = 1;
107 				if((f += 1) >= N_FREE)
108 					break;
109 			}
110 		}
111 	}
112 	size *= 2; /* should be big enough */
113 
114 	tinfo("Testing mmap shared memory");
115 
116 	store = tstfile("map", -1);
117 	unlink(store); /* start with a fresh file */
118 	if(!(dc = vmdcshare(store, -1, size, -1)) ||
119 	   !(vm = vmopen(dc, Vmbest, 0)) )
120 		terror("Can't open shared region");
121 
122 	if(working(store, -1, size) < 0 )
123 		terror("Failed simulation");
124 
125 	if(vmstat(vm, &vmst) < 0 )
126 		terror("Can't get statistics for region");
127 	tinfo("Statistics: extent=%d busy=(n=%d,z=%d) free=(n=%d,z=%d)",
128 		vmst.extent, vmst.n_busy, vmst.s_busy, vmst.n_free, vmst.s_free);
129 	if(vmst.n_busy != (N_ALLOC-N_FREE))
130 		terror("Number of busy block %d is not the expected %d",
131 			vmst.n_busy, (N_ALLOC-N_FREE) );
132 
133 	vmclose(vm);
134 
135 	texit(0);
136 }
137