1 /* 2 * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. 3 * AUTHOR : William Roske 4 * CO-PILOT : Dave Fenner 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of version 2 of the GNU General Public License as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it would be useful, but 11 * WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 * 14 * Further, this software is distributed without any warranty that it is 15 * free of the rightful claim of any third person regarding infringement 16 * or the like. Any license provided herein, whether implied or 17 * otherwise, applies only to this software file. Patent licenses, if 18 * any, provided herein do not apply to combinations of this program with 19 * other software, or any other product whatsoever. 20 * 21 * You should have received a copy of the GNU General Public License along 22 * with this program; if not, write the Free Software Foundation, Inc., 23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 24 * 25 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 26 * Mountain View, CA 94043, or: 27 * 28 * http://www.sgi.com 29 * 30 * For further information regarding this notice, see: 31 * 32 * http://oss.sgi.com/projects/GenInfo/NoticeExplan/ 33 * 34 */ 35 36 #include <unistd.h> 37 #include <errno.h> 38 #include <string.h> 39 #include <signal.h> 40 #include <sys/param.h> 41 #include <sys/resource.h> 42 43 #include "test.h" 44 45 #ifndef BSIZE 46 #define BSIZE BBSIZE 47 #endif 48 49 void setup(); 50 void cleanup(); 51 52 #define MAX_SIZE_LC 1000 /* loop count test will reach max size */ 53 54 char *TCID = "brk01"; 55 int TST_TOTAL = 1; 56 57 long Max_brk_byte_size; 58 long Beg_brk_val; 59 60 #if !defined(UCLINUX) 61 62 int main(int ac, char **av) 63 { 64 int lc; 65 int incr; 66 long nbrkpt; /* new brk point value */ 67 long cur_brk_val; /* current size returned by sbrk */ 68 long aft_brk_val; /* current size returned by sbrk */ 69 70 tst_parse_opts(ac, av, NULL, NULL); 71 72 setup(); 73 74 /* 75 * Attempt to control how fast we get to test max size. 76 * Every MAX_SIZE_LC'th lc will be fastest test will reach max size. 77 */ 78 incr = (Max_brk_byte_size - Beg_brk_val) / (MAX_SIZE_LC / 2); 79 80 if ((incr * 2) < 4096) /* make sure that process will grow */ 81 incr += 4096 / 2; 82 83 for (lc = 0; TEST_LOOPING(lc); lc++) { 84 85 tst_count = 0; 86 87 /* 88 * Determine new value to give brk 89 * Every even lc value, grow by 2 incr and 90 * every odd lc value, strink by one incr. 91 * If lc is equal to 3, no change, special case. 92 */ 93 cur_brk_val = (long)sbrk(0); 94 if (lc == 3) { 95 nbrkpt = cur_brk_val; /* no change, special one time case */ 96 } else if ((lc % 2) == 0) { 97 /* 98 * grow 99 */ 100 nbrkpt = cur_brk_val + (2 * incr); 101 102 if (nbrkpt > Max_brk_byte_size) 103 nbrkpt = Beg_brk_val; /* start over */ 104 105 } else { 106 /* 107 * shrink 108 */ 109 nbrkpt = cur_brk_val - incr; 110 } 111 112 /**** 113 printf("cur_brk_val = %d, nbrkpt = %d, incr = %d, lc = %d\n", 114 cur_brk_val, nbrkpt, incr, lc); 115 ****/ 116 117 TEST(brk((char *)nbrkpt)); 118 119 if (TEST_RETURN == -1) { 120 121 aft_brk_val = (long)sbrk(0); 122 tst_resm(TFAIL | TTERRNO, 123 "brk(%ld) failed (size before %ld, after %ld)", 124 nbrkpt, cur_brk_val, aft_brk_val); 125 126 } else { 127 aft_brk_val = (long)sbrk(0); 128 if (aft_brk_val == nbrkpt) { 129 130 tst_resm(TPASS, 131 "brk(%ld) returned %ld, new size verified by sbrk", 132 nbrkpt, TEST_RETURN); 133 } else { 134 tst_resm(TFAIL, 135 "brk(%ld) returned %ld, sbrk before %ld, after %ld", 136 nbrkpt, TEST_RETURN, 137 cur_brk_val, aft_brk_val); 138 } 139 } 140 141 } 142 143 cleanup(); 144 tst_exit(); 145 } 146 147 void setup(void) 148 { 149 unsigned long max_size; 150 int ncpus; 151 unsigned long ulim_sz; 152 unsigned long usr_mem_sz; 153 struct rlimit lim; 154 155 tst_sig(NOFORK, DEF_HANDLER, cleanup); 156 157 /*if ((ulim_sz=ulimit(3,0)) == -1) 158 tst_brkm(TBROK|TERRNO, cleanup, "ulimit(3,0) failed"); */ 159 160 if (getrlimit(RLIMIT_DATA, &lim) == -1) 161 tst_brkm(TBROK | TERRNO, cleanup, 162 "getrlimit(RLIMIT_DATA,%p) failed", &lim); 163 ulim_sz = lim.rlim_cur; 164 165 /* 166 * On IRIX, which is a demand paged system, memory is managed 167 * different than on Crays systems. For now, pick some value. 168 */ 169 usr_mem_sz = 1024 * 1024 * sizeof(long); 170 171 if ((ncpus = sysconf(_SC_NPROCESSORS_ONLN)) == -1) 172 tst_brkm(TBROK | TERRNO, cleanup, 173 "sysconf(_SC_NPROCESSORS_ONLN) failed"); 174 175 /* 176 * allow 2*ncpus copies to run. 177 * never attempt to take more than a * 1/4 of memory (by single test) 178 */ 179 180 if (ulim_sz < usr_mem_sz) 181 max_size = ulim_sz; 182 else 183 max_size = usr_mem_sz; 184 185 max_size = max_size / (2 * ncpus); 186 187 if (max_size > (usr_mem_sz / 4)) 188 max_size = usr_mem_sz / 4; /* only fourth mem by single test */ 189 190 Beg_brk_val = (long)sbrk(0); 191 192 /* 193 * allow at least 4 times a big as current. 194 * This will override above code. 195 */ 196 if (max_size < Beg_brk_val * 4) /* running on small mem and/or high # cpus */ 197 max_size = Beg_brk_val * 4; 198 199 Max_brk_byte_size = max_size; 200 201 TEST_PAUSE; 202 203 } 204 205 void cleanup(void) 206 { 207 } 208 209 #else 210 211 int main(void) 212 { 213 tst_brkm(TCONF, NULL, "test is not available on uClinux"); 214 } 215 216 #endif /* if !defined(UCLINUX) */ 217