Initial commit: Schunix as it stands before the SchOS rename
An x86-64 operating system built from xv6, now largely rewritten: SMP, a copy-on-write root filesystem (SchFS), PCI/USB/virtio drivers, a TTF rasteriser, and a Linux-numbered syscall ABI. No history before this point -- the tree was never under version control. This commit exists so the rename that follows has something to undo to.
This commit is contained in:
commit
d0f7acf9eb
275 changed files with 51417 additions and 0 deletions
112
cmd/shmtest/main.c
Normal file
112
cmd/shmtest/main.c
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
// shmtest -- prove that shared memory is actually shared, and that a
|
||||
// file-backed mmap returns the file.
|
||||
//
|
||||
// Both of these are things you cannot check by reading a return value. shmget
|
||||
// and shmat returned -ENOSYS until now, and mmap of a file "succeeded" while
|
||||
// handing back zeroed anonymous pages -- a lie that looks exactly like
|
||||
// success. The only convincing test is for one process to write and a
|
||||
// different one to read.
|
||||
//
|
||||
// shmtest run every check
|
||||
//
|
||||
// Prints one line per check, and a final verdict a script can grep for.
|
||||
|
||||
#include "types.h"
|
||||
#include "user.h"
|
||||
#include "fcntl.h"
|
||||
|
||||
#define PROT_READ 0x1
|
||||
#define PROT_WRITE 0x2
|
||||
#define MAP_PRIVATE 0x02
|
||||
#define MAP_SHARED 0x01
|
||||
#define IPC_PRIVATE 0
|
||||
#define IPC_CREAT 01000
|
||||
|
||||
static int failures;
|
||||
|
||||
static void
|
||||
puts_(const char *s)
|
||||
{
|
||||
int n = 0;
|
||||
while (s[n]) n++;
|
||||
write(1, (void*)s, n);
|
||||
}
|
||||
|
||||
static void
|
||||
check(int ok, const char *what)
|
||||
{
|
||||
puts_(ok ? " [ok] " : " FAIL: ");
|
||||
puts_(what);
|
||||
puts_("\n");
|
||||
if (!ok) failures++;
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
// --- shared memory ----------------------------------------------------
|
||||
int id = shmget(IPC_PRIVATE, 8192, IPC_CREAT | 0600);
|
||||
check(id >= 0, "shmget created a segment");
|
||||
if (id < 0) { puts_("shmtest: FAILED\n"); return 1; }
|
||||
|
||||
char *p = shmat(id, 0, 0);
|
||||
check((long)p > 0, "shmat mapped it");
|
||||
if ((long)p <= 0) { puts_("shmtest: FAILED\n"); return 1; }
|
||||
|
||||
// A fresh segment must be zeroed, or it leaks whatever the previous
|
||||
// tenant left in those pages to whoever gets them next.
|
||||
int zeroed = 1;
|
||||
for (int i = 0; i < 8192; i++)
|
||||
if (p[i] != 0) { zeroed = 0; break; }
|
||||
check(zeroed, "a new segment reads as zeros");
|
||||
|
||||
p[0] = 'P';
|
||||
p[1] = 0;
|
||||
|
||||
int pid = fork();
|
||||
if (pid == 0) {
|
||||
// The child inherited the attachment through fork. If the pages had
|
||||
// been copied instead of shared, the parent would never see this.
|
||||
p[0] = 'C';
|
||||
p[100] = 'X';
|
||||
exit();
|
||||
}
|
||||
wait();
|
||||
|
||||
check(p[0] == 'C', "a write by the child is visible in the parent");
|
||||
check(p[100] == 'X', "and so is one further into the segment");
|
||||
|
||||
// --- file-backed mmap --------------------------------------------------
|
||||
int fd = open("/tmp/shmtest.dat", O_CREATE | O_RDWR);
|
||||
check(fd >= 0, "created a file to map");
|
||||
if (fd >= 0) {
|
||||
write(fd, "SCHUNIX-MMAP-OK", 15);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
fd = open("/tmp/shmtest.dat", O_RDONLY);
|
||||
if (fd >= 0) {
|
||||
char *m = mmap(0, 4096, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
int ok = ((long)m > 0) &&
|
||||
m[0]=='S' && m[1]=='C' && m[2]=='H' && m[3]=='U' &&
|
||||
m[8]=='M' && m[13]=='O' && m[14]=='K';
|
||||
check(ok, "mmap of a file returns the file, not zeros");
|
||||
close(fd);
|
||||
} else {
|
||||
check(0, "mmap of a file returns the file, not zeros");
|
||||
}
|
||||
|
||||
// MAP_SHARED + PROT_WRITE on a file cannot be honoured without a page
|
||||
// cache, and is refused rather than quietly downgraded to a private copy.
|
||||
fd = open("/tmp/shmtest.dat", O_RDWR);
|
||||
if (fd >= 0) {
|
||||
void *m = mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
check((long)m < 0, "writable MAP_SHARED on a file is refused, not faked");
|
||||
close(fd);
|
||||
}
|
||||
|
||||
check(shmdt(p) == 0, "shmdt released the attachment");
|
||||
|
||||
puts_(failures ? "shmtest: FAILED\n" : "shmtest: all checks passed\n");
|
||||
return failures ? 1 : 0;
|
||||
}
|
||||
Loading…
Reference in a new issue