xref: /freebsd/tools/test/stress2/testcases/swap/swap.c (revision ac19e54390a0ff3c273cac514f404e867e26682a)
18a272653SPeter Holm /*-
28a272653SPeter Holm  * Copyright (c) 2008 Peter Holm <pho@FreeBSD.org>
38a272653SPeter Holm  * All rights reserved.
48a272653SPeter Holm  *
58a272653SPeter Holm  * Redistribution and use in source and binary forms, with or without
68a272653SPeter Holm  * modification, are permitted provided that the following conditions
78a272653SPeter Holm  * are met:
88a272653SPeter Holm  * 1. Redistributions of source code must retain the above copyright
98a272653SPeter Holm  *    notice, this list of conditions and the following disclaimer.
108a272653SPeter Holm  * 2. Redistributions in binary form must reproduce the above copyright
118a272653SPeter Holm  *    notice, this list of conditions and the following disclaimer in the
128a272653SPeter Holm  *    documentation and/or other materials provided with the distribution.
138a272653SPeter Holm  *
148a272653SPeter Holm  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
158a272653SPeter Holm  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
168a272653SPeter Holm  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
178a272653SPeter Holm  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
188a272653SPeter Holm  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
198a272653SPeter Holm  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
208a272653SPeter Holm  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
218a272653SPeter Holm  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
228a272653SPeter Holm  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
238a272653SPeter Holm  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
248a272653SPeter Holm  * SUCH DAMAGE.
258a272653SPeter Holm  *
268a272653SPeter Holm  */
278a272653SPeter Holm 
288a272653SPeter Holm #include <sys/types.h>
298a272653SPeter Holm #include <sys/resource.h>
308a272653SPeter Holm #include <sys/sysctl.h>
318a272653SPeter Holm #include <sys/time.h>
328a272653SPeter Holm 
338a272653SPeter Holm #include <err.h>
348a272653SPeter Holm #include <stdio.h>
358a272653SPeter Holm #include <stdlib.h>
368a272653SPeter Holm #include <unistd.h>
378a272653SPeter Holm 
388a272653SPeter Holm #include "stress.h"
398a272653SPeter Holm 
408a272653SPeter Holm #if defined(__LP64__)
418a272653SPeter Holm #define MINLEFT (1792LL * 1024 * 1024)
428a272653SPeter Holm #else
438a272653SPeter Holm #define MINLEFT (1024LL * 1024 * 1024)
448a272653SPeter Holm #endif
458a272653SPeter Holm 
468a272653SPeter Holm static int64_t size;
478a272653SPeter Holm 
488a272653SPeter Holm int
setup(int nb)498a272653SPeter Holm setup(int nb)
508a272653SPeter Holm {
518a272653SPeter Holm 	struct rlimit rlp;
528a272653SPeter Holm 	int64_t  mem, swapinfo;
538a272653SPeter Holm 	int mi, mx, pct;
548a272653SPeter Holm 	char *cp;
558a272653SPeter Holm 
568a272653SPeter Holm 	if (nb == 0) {
578a272653SPeter Holm 		mem = usermem();
588a272653SPeter Holm 		swapinfo = swap();
598a272653SPeter Holm 
608a272653SPeter Holm 		pct = 0;
618a272653SPeter Holm 		if (op->hog == 0) {
628a272653SPeter Holm 			mi = 80;
638a272653SPeter Holm 			mx = 100;
648a272653SPeter Holm 		}
658a272653SPeter Holm 
668a272653SPeter Holm 		if (op->hog == 1) {
678a272653SPeter Holm 			mi = 100;
688a272653SPeter Holm 			mx = 110;
698a272653SPeter Holm 		}
708a272653SPeter Holm 
718a272653SPeter Holm 		if (op->hog == 2) {
728a272653SPeter Holm 			mi = 110;
738a272653SPeter Holm 			mx = 120;
748a272653SPeter Holm 		}
758a272653SPeter Holm 
768a272653SPeter Holm 		if (op->hog >= 3) {
778a272653SPeter Holm 			mi = 120;
788a272653SPeter Holm 			mx = 130;
798a272653SPeter Holm 		}
808a272653SPeter Holm 		if ((cp = getenv("MAXSWAPPCT")) != NULL && *cp != '\0') {
818a272653SPeter Holm 			mx = atoi(cp);
828a272653SPeter Holm 			mi = mx - 10;
838a272653SPeter Holm 		}
848a272653SPeter Holm 		pct = random_int(mi, mx);
858a272653SPeter Holm 
868a272653SPeter Holm 		if (swapinfo == 0) {
878a272653SPeter Holm 			pct = random_int(30, 50);
888a272653SPeter Holm 			if (mem <= MINLEFT) {
898a272653SPeter Holm 				putval(0);
908a272653SPeter Holm 				_exit(1);
918a272653SPeter Holm 			}
928a272653SPeter Holm 			mem -= MINLEFT;
938a272653SPeter Holm 			size = mem / 100 * pct;
948a272653SPeter Holm 		} else {
958a272653SPeter Holm 			size = mem / 100 * pct;
968a272653SPeter Holm 			if (size > mem + swapinfo / 4) {
978a272653SPeter Holm 				size = mem + swapinfo / 4;
988a272653SPeter Holm 				pct = size * 100 / mem;
998a272653SPeter Holm 			}
1008a272653SPeter Holm 		}
1018a272653SPeter Holm 
1028a272653SPeter Holm 		size = size / op->incarnations;
1038a272653SPeter Holm 
1048a272653SPeter Holm 		if (getrlimit(RLIMIT_DATA, &rlp) < 0)
1058a272653SPeter Holm 			err(1,"getrlimit");
1068a272653SPeter Holm 		rlp.rlim_cur -= 1024 * 1024;
1078a272653SPeter Holm 
1088a272653SPeter Holm 		if (size > rlp.rlim_cur)
1098a272653SPeter Holm 			size = rlp.rlim_cur;
1108a272653SPeter Holm 		putval(size);
1118a272653SPeter Holm 
1128a272653SPeter Holm 		if (op->verbose > 1 && nb == 0)
1138a272653SPeter Holm 			printf("setup: pid %d, %d%%. Total %dMb, %d thread(s).\n",
1148a272653SPeter Holm 			    getpid(), pct, (int)(size / 1024 / 1024 *
1158a272653SPeter Holm 			    op->incarnations), op->incarnations);
1168a272653SPeter Holm 	} else
1178a272653SPeter Holm 		size = getval();
1188a272653SPeter Holm 
1198a272653SPeter Holm 	if (size == 0)
1208a272653SPeter Holm 		exit(1);
1218a272653SPeter Holm 
1228a272653SPeter Holm 	return (0);
1238a272653SPeter Holm }
1248a272653SPeter Holm 
1258a272653SPeter Holm void
cleanup(void)1268a272653SPeter Holm cleanup(void)
1278a272653SPeter Holm {
1288a272653SPeter Holm }
1298a272653SPeter Holm 
1308a272653SPeter Holm int
test(void)1318a272653SPeter Holm test(void)
1328a272653SPeter Holm {
1338a272653SPeter Holm 	time_t start;
1348a272653SPeter Holm 	int64_t i, oldsize;
1358a272653SPeter Holm 	int page;
1368a272653SPeter Holm 	char *c;
1378a272653SPeter Holm 
1388a272653SPeter Holm 	if (size == 0)
1398a272653SPeter Holm 		return (0);
1408a272653SPeter Holm 	oldsize = size;
1418a272653SPeter Holm 	c = malloc(size);
1428a272653SPeter Holm 	while (c == NULL && done_testing == 0) {
1438a272653SPeter Holm 		size -=  1024 * 1024;
1448a272653SPeter Holm 		c = malloc(size);
1458a272653SPeter Holm 	}
1468a272653SPeter Holm 	if (op->verbose > 1 && size != oldsize)
1478a272653SPeter Holm 		printf("Malloc size changed from %d Mb to %d Mb\n",
1488a272653SPeter Holm 		    (int)(oldsize / 1024 / 1024), (int)(size / 1024 / 102));
1498a272653SPeter Holm 	page = getpagesize();
1508a272653SPeter Holm 	start = time(NULL);	/* Livelock workaround */
1518a272653SPeter Holm 	while (done_testing == 0 &&
1528a272653SPeter Holm 			(time(NULL) - start) < op->run_time) {
1538a272653SPeter Holm 		i = 0;
1548a272653SPeter Holm 		while (i < size && done_testing == 0) {
1558a272653SPeter Holm 			c[i] = 0;
1568a272653SPeter Holm 			i += page;
1578a272653SPeter Holm 		}
158*ac19e543SPeter Holm 		if (arc4random() % 100 < 10)
159*ac19e543SPeter Holm 			usleep(10000);
1608a272653SPeter Holm 	}
1618a272653SPeter Holm 	free((void *)c);
1628a272653SPeter Holm 
1638a272653SPeter Holm 	return (0);
1648a272653SPeter Holm }
165