>>5
I ran your program and my system stayed responsive. The problem is that you think
malloc works like it did on your old 286 running DOS. It doesn't allocate physical RAM on any modern OS I know of.
Try running the following program. It only works on Linux, and it does NOT require root. It only opens one file,
/dev/random, just to seed a few PRNGs.
#include <sys/mman.h>
#include <sys/sysinfo.h>
#include <err.h>
#include <stdint.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#define THREADS_PER_CPU 10
static unsigned char *thrash_ptr;
static size_t thrash_psize, thrash_pcount;
static pthread_mutex_t thrash_mutex;
static int thrash_random, thrash_active;
static void thrash(void)
{
uint32_t x[2], a = 4294967118UL, v;
uint64_t t;
int r;
size_t p;
unsigned char *ptr = thrash_ptr;
size_t psize = thrash_psize, pcount = thrash_pcount;
r = read(thrash_random, &x, sizeof(x));
if (r < 0)
err(1, "/dev/random");
if (r < (int)sizeof(x))
errx(1, "Could not read enough random data");
x[0] |= !x[0];
x[1] |= !x[1];
while (1) {
t = (uint64_t)a * x[0] + x[1];
x[0] = t;
x[1] = t >> 32;
p = (size_t)x[0] % pcount;
v = (size_t)x[0] / pcount;
ptr[p * psize] = v;
}
}
static void *thrash_thread(void *p)
{
(void)p;
int r;
r = pthread_mutex_lock(&thrash_mutex);
if (r) errx(1, "pthread_mutex_lock");
printf("Thread %i active\n", ++thrash_active);
r = pthread_mutex_unlock(&thrash_mutex);
if (r) errx(1, "pthread_mutex_unlock");
thrash();
return NULL;
}
static void countdown(void)
{
int i;
fputs("Last chance to stop...", stdout);
fflush(stdout);
sleep(1);
for (i = 3; i > 0; --i) {
printf(" %i...", i);
fflush(stdout);
sleep(1);
}
fputs(" 0\n", stdout);
}
int main(int argc, char *argv[])
{
struct sysinfo sinfo;
int r, fd;
void *mem;
size_t totalram, nthread, i;
long pagesize, nproc;
pthread_attr_t attr;
pthread_t *thread;
pthread_mutexattr_t mattr;
(void)argc;
(void)argv;
/* Map memory */
r = sysinfo(&sinfo);
if (r)
err(1, "sysinfo");
if (sinfo.totalram > SIZE_MAX / sinfo.mem_unit)
errx(1, "Too much ram, not enough address space");
totalram = (size_t)sinfo.totalram * sinfo.mem_unit;
pagesize = sysconf(_SC_PAGESIZE);
if (pagesize <= 0)
errx(1, "Can't get page size");
printf("Page size: %li\n", pagesize);
mem = mmap(NULL, totalram, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
if (mem == (void *)-1)
err(1, "mmap");
thrash_ptr = mem;
thrash_psize = pagesize;
thrash_pcount = totalram / (size_t)pagesize
+ ((totalram % pagesize) ? 1 : 0);
/* Count CPUs */
nproc = sysconf(_SC_NPROCESSORS_ONLN);
if (nproc <= 1)
nproc = 1;
printf("Total RAM: %zu (%zu pages of %zu bytes)\n"
"Number of CPUs: %li\n",
totalram, thrash_pcount, thrash_psize, nproc);
/* Open /dev/random for seeds */
fd = open("/dev/random", O_RDONLY);
if (fd < 0)
err(1, "/dev/random");
thrash_random = fd;
/* Create threads */
r = pthread_mutexattr_init(&mattr);
if (r) goto onethread;
r = pthread_mutex_init(&thrash_mutex, &mattr);
if (r) goto onethread;
r = pthread_mutex_lock(&thrash_mutex);
if (r) goto onethread;
nthread = (size_t)nproc * THREADS_PER_CPU;
thread = malloc(sizeof(*thread) * nthread);
if (!thread)
err(1, "malloc");
r = pthread_attr_init(&attr);
if (r) goto onethread;
for (i = 0; i < nthread; ++i) {
r = pthread_create(&thread[i], &attr, thrash_thread, NULL);
if (r) break;
}
nthread = i;
countdown();
r = pthread_mutex_unlock(&thrash_mutex);
pause();
return 0;
onethread:
countdown();
puts("Using only one thread");
thrash();
return 0;
}