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