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