#pragma once // The timer interrupt rate the kernel is built around. Everything that turns // ticks into a duration divides by this. It used to be the literal 100 written // out at each site, which made it look like a fact about the hardware; it is // not. It is a target, and kernel/arch/x86_64/lapic.c calibrates the LAPIC // timer against the PIT to actually hit it. #define HZ 100 // timer interrupts per second // The tick rate the *user-space ABI* is defined in, which is a different thing // from HZ and must not follow it. glibc and musl both answer sysconf(_SC_CLK_TCK) // with a hardcoded 100, so times() and /proc/stat are read as hundredths of a // second no matter what the kernel's internal rate is. Linux calls this USER_HZ // and scales at the syscall boundary; so does SchOS, in the two places below. #define USER_HZ 100 // Converting a POSIX timespec/timeval into ticks. These used to appear as the // bare literals 10000000 and 10000 at each call site, where they looked like // magic numbers rather than what they are: the length of one tick, expressed // in the units the caller happens to be using. #define NSEC_PER_TICK (1000000000 / HZ) #define USEC_PER_TICK (1000000 / HZ) #define MSEC_PER_TICK (1000 / HZ) #define NPROC 128 // maximum number of processes #define KSTACKSIZE 4096 // size of per-process kernel stack (increased for x64) #define KSTACK_CANARY 0xDEADC0DEDEADC0DEULL // sentinel at kstack[0], see kstack_check_canary() #define NCPU 16 // maximum number of CPUs #define NOFILE 128 // open files per process #define NFILE 512 // open files per system #define NINODE 200 // maximum number of active i-nodes #define NDEV 11 // maximum major device number #define RAMDISK_DEV 2 // memory-backed block device (kernel/dev/ramdisk.c) #define USBDISK_DEV 3 // USB mass storage (kernel/drivers/usb_storage.c) // Device the root filesystem is mounted from. Building with RAMROOT=1 defines // RAMDISK_ROOT and boots from the SCHFS image linked into the kernel instead // of the IDE disk, leaving the physical disk free to be reformatted from a // running system. See kernel/dev/ramdisk.c. #ifdef RAMDISK_ROOT #define ROOTDEV RAMDISK_DEV #else #define ROOTDEV 1 // device number of file system root disk #endif #define MAXARG 32 // max exec arguments #define MAXENV 64 // max environment variables passed through exec #define MAXPATH 128 // max path #define MAXOPBLOCKS 30 // max # of blocks any FS op writes #define LOGSIZE (MAXOPBLOCKS*3) // max data blocks in on-disk log // Disk block cache, in blocks. 256 * BSIZE = 1 MB. // // Was MAXOPBLOCKS*3 = 90 blocks, and at the old 1 KB BSIZE that is a 90 KB // cache -- smaller than the toybox binary that every single command execs. So // nothing was ever still resident on the next command and each one paid the // full read again. 1 MB holds toybox with room to spare, which is what makes // the *second* command fast rather than just the first. // // Sized rather than maximised: these are statically allocated in bio.c, so // this is memory the system always spends. 1 MB is affordable on a machine // with tens of megabytes; 8 MB would not be. #define NBUF 256 #define FSSIZE 150000 // size of file system in blocks // Network interfaces the stack will attach. Two is already an ordinary machine // -- a laptop with Ethernet plus a virtual adapter -- and each one costs a // struct netif, so the limit is about keeping a fixed array honest rather than // about memory. #define NETIF_MAX 4