diff --git a/elks/arch/i86/drivers/char/mem.c b/elks/arch/i86/drivers/char/mem.c index 9c28b8c27..0717d3e9e 100644 --- a/elks/arch/i86/drivers/char/mem.c +++ b/elks/arch/i86/drivers/char/mem.c @@ -29,96 +29,134 @@ #include #include -#define DEV_MEM_MINOR 1 /* unused */ -#define DEV_KMEM_MINOR 2 -#define DEV_NULL_MINOR 3 -#define DEV_PORT_MINOR 4 -#define DEV_ZERO_MINOR 5 -#define DEV_FULL_MINOR 6 /* unused */ +#define DEV_MEM_MINOR 1 /* unused */ +#define DEV_KMEM_MINOR 2 +#define DEV_NULL_MINOR 3 +#define DEV_PORT_MINOR 4 +#define DEV_ZERO_MINOR 5 +#define DEV_MAX_MINOR 5 /* - * generally useful code... + * /dev/null code */ -static int memory_lseek(struct inode *inode, struct file *filp, loff_t offset, - unsigned int origin) +static int null_lseek(struct inode *inode, struct file *filp, loff_t offset, int origin) { - debugmem("mem_lseek()\n"); - switch (origin) { - case 1: - offset += filp->f_pos; - case 0: - if (offset >= 0) - break; - default: - return -EINVAL; - } - if (offset != filp->f_pos) { - filp->f_pos = offset; - } + filp->f_pos = 0; return 0; } -/* - * /dev/null code - */ -int null_lseek(struct inode *inode, struct file *filp, off_t offset, int origin) +static size_t null_read(struct inode *inode, struct file *filp, char *data, size_t len) { - debugmem("null_lseek()\n"); - filp->f_pos = 0; return 0; } -size_t null_read(struct inode *inode, struct file *filp, char *data, size_t len) +static size_t null_write(struct inode *inode, struct file *filp, char *data, size_t len) { - debugmem("null_read()\n"); - return 0; + return len; } -size_t null_write(struct inode *inode, struct file *filp, char *data, size_t len) +/* + * /dev/zero code + */ +static size_t zero_read(struct inode *inode, struct file *filp, char *data, size_t len) { - debugmem("null write: ignoring %d bytes!\n", len); + fmemsetb(data, current->t_regs.ds, 0, len); + filp->f_pos += len; return len; } /* - * /dev/port code + * /dev/kmem code */ -#if defined(CONFIG_CHAR_DEV_MEM_PORT_READ) || defined(CONFIG_CHAR_DEV_MEM_PORT_WRITE) -int port_lseek(struct inode *inode, struct file *filp, off_t offset, int origin) +static size_t kmem_read(struct inode *inode, struct file *filp, char *data, size_t len) { - debugmem("port_lseek()\n"); + seg_t sseg = (unsigned long)filp->f_pos >> 4; + segext_t soff = filp->f_pos & 0x0F; - switch (origin) - { - case 0: /* SEEK_SET */ - break; + fmemcpyb((byte_t *)data, current->t_regs.ds, (byte_t *)soff, sseg, (word_t) len); + filp->f_pos += len; + return len; +} - case 1: /* SEEK_CUR */ - offset += filp->f_pos; - break; +static size_t kmem_write(struct inode *inode, struct file *filp, char *data, size_t len) +{ + seg_t dseg = (unsigned long)filp->f_pos >> 4; + segext_t doff = filp->f_pos & 0x0F; - case 2: /* SEEK_END */ - offset = port_MAX + offset; - break; + /* FIXME: very dangerous! */ + fmemcpyb((byte_t *)doff, dseg, (byte_t *)data, current->t_regs.ds, (word_t) len); + filp->f_pos += len; + return len; +} - default: - return -EINVAL; - } +static int kmem_ioctl(struct inode *inode, struct file *file, int cmd, char *arg) +{ + unsigned short retword; + struct mem_usage mu; - if(offset < 0) - offset = 0; - else if(offset > port_MAX) - offset = port_MAX; + switch (cmd) { + case MEM_GETTASK: + retword = (unsigned short)task; + break; + case MEM_GETMAXTASKS: + retword = max_tasks; + break; + case MEM_GETCS: + retword = kernel_cs; + break; + case MEM_GETDS: + retword = kernel_ds; + break; + case MEM_GETFARTEXT: + retword = (unsigned)((long)buffer_init >> 16); + break; + case MEM_GETUSAGE: + mm_get_usage (&(mu.free_memory), &(mu.used_memory)); + memcpy_tofs(arg, &mu, sizeof(struct mem_usage)); + return 0; + case MEM_GETHEAP: + retword = (unsigned short) &_heap_all; + break; + case MEM_GETJIFFADDR: + retword = (unsigned short) &jiffies; + break; + case MEM_GETSEGALL: + retword = (unsigned short) &_seg_all; + break; + case MEM_GETUPTIME: +#ifdef CONFIG_CPU_USAGE + retword = (unsigned short) &uptime; + break; +#endif + /* fall thru */ + default: + return -EINVAL; + } + put_user(retword, arg); + return 0; +} +static int memory_lseek(struct inode *inode, struct file *filp, loff_t offset, int origin) +{ + switch (origin) { + case 1: + offset += filp->f_pos; + /* fall thru */ + case 0: + if (offset >= 0) + break; + default: + return -EINVAL; + } filp->f_pos = offset; - debugmem("port_lseek: 0x%02X\n", (unsigned)filp->f_pos); - return 0; } -#endif +/* + * /dev/port code + */ #if defined(CONFIG_CHAR_DEV_MEM_PORT_READ) -size_t port_read(struct inode *inode, struct file *filp, char *data, size_t len) +static size_t port_read(struct inode *inode, struct file *filp, char *data, size_t len) { size_t i; @@ -135,11 +173,11 @@ size_t port_read(struct inode *inode, struct file *filp, char *data, size_t len) return i; } #else -# define port_read NULL +# define port_read NULL #endif #if defined(CONFIG_CHAR_DEV_MEM_PORT_WRITE) -size_t port_write(struct inode *inode, struct file *filp, char *data, size_t len) +static size_t port_write(struct inode *inode, struct file *filp, char *data, size_t len) { size_t i; @@ -156,211 +194,123 @@ size_t port_write(struct inode *inode, struct file *filp, char *data, size_t len return i; } #else -# define port_write NULL +# define port_write NULL #endif -#if UNUSED -/* - * /dev/full code - */ -size_t full_read(struct inode *inode, struct file *filp, char *data, size_t len) -{ - debugmem("full_read()\n"); - filp->f_pos += len; - return len; -} - -size_t full_write(struct inode *inode, struct file *filp, char *data, size_t len) -{ - debugmem("full_write: objecting to %d bytes!\n", len); - return -ENOSPC; -} -#endif - -/* - * /dev/zero code - */ -size_t zero_read(struct inode *inode, struct file *filp, char *data, size_t len) +#if defined(CONFIG_CHAR_DEV_MEM_PORT_READ) || defined(CONFIG_CHAR_DEV_MEM_PORT_WRITE) +static int port_lseek(struct inode *inode, struct file *filp, loff_t offset, int origin) { - debugmem("zero_read()\n"); - fmemsetb(data, current->t_regs.ds, 0, len); - filp->f_pos += len; - return (size_t)len; -} + debugmem("port_lseek()\n"); -static unsigned short int split_seg_off(unsigned short int *offset, long int posn) -{ - *offset = (unsigned short int) (((unsigned long int) posn) & 0xF); - return (unsigned short int) (((unsigned long int) posn) >> 4); -} + switch (origin) + { + case 0: /* SEEK_SET */ + break; -/* - * /dev/kmem code - */ -size_t kmem_read(struct inode *inode, register struct file *filp, char *data, size_t len) -{ - unsigned short int sseg, soff; + case 1: /* SEEK_CUR */ + offset += filp->f_pos; + break; - debugmem("kmem_read()\n"); - sseg = split_seg_off(&soff, filp->f_pos); - debugmem("Reading %u %p %p.\n", len, sseg, soff); - fmemcpyb((byte_t *)data, current->t_regs.ds, (byte_t *)soff, sseg, (word_t) len); - filp->f_pos += len; - return (size_t) len; -} + case 2: /* SEEK_END */ + offset = port_MAX + offset; + break; -size_t kmem_write(struct inode *inode, register struct file *filp, char *data, size_t len) -{ - unsigned short int dseg, doff; + default: + return -EINVAL; + } - debugmem("kmem_write()\n"); - dseg = split_seg_off(&doff, filp->f_pos); - debugmem("Writing to %d:%d\n", dseg, doff); - fmemcpyb((byte_t *)doff, dseg, (byte_t *)data, current->t_regs.ds, (word_t) len); - filp->f_pos += len; - return len; -} + if(offset < 0) + offset = 0; + else if(offset > port_MAX) + offset = port_MAX; -int kmem_ioctl(struct inode *inode, struct file *file, int cmd, char *arg) -{ - unsigned short retword; - struct mem_usage mu; + filp->f_pos = offset; + debugmem("port_lseek: 0x%02X\n", (unsigned)filp->f_pos); - switch (cmd) { - case MEM_GETTASK: - retword = (unsigned short)task; - break; - case MEM_GETMAXTASKS: - retword = max_tasks; - break; - case MEM_GETCS: - retword = kernel_cs; - break; - case MEM_GETDS: - retword = kernel_ds; - break; - case MEM_GETFARTEXT: - retword = (unsigned)((long)buffer_init >> 16); - break; - case MEM_GETUSAGE: - mm_get_usage (&(mu.free_memory), &(mu.used_memory)); - memcpy_tofs(arg, &mu, sizeof(struct mem_usage)); - return 0; - case MEM_GETHEAP: - retword = (unsigned short) &_heap_all; - break; - case MEM_GETJIFFADDR: - retword = (unsigned short) &jiffies; - break; - case MEM_GETUPTIME: -#ifdef CONFIG_CPU_USAGE - retword = (unsigned short) &uptime; - break; -#endif - default: - return -EINVAL; - } - put_user(retword, arg); return 0; } -static struct file_operations null_fops = { - null_lseek, /* lseek */ - null_read, /* read */ - null_write, /* write */ - NULL, /* readdir */ - NULL, /* select */ - NULL, /* ioctl */ - NULL, /* open */ - NULL /* release */ -}; - -#if defined(CONFIG_CHAR_DEV_MEM_PORT_READ) || defined(CONFIG_CHAR_DEV_MEM_PORT_WRITE) static struct file_operations port_fops = { - port_lseek, /* lseek */ - port_read, /* read */ - port_write, /* write */ - NULL, /* readdir */ - NULL, /* select */ - NULL, /* ioctl */ - NULL, /* open */ - NULL /* release */ + port_lseek, /* lseek */ + port_read, /* read */ + port_write, /* write */ + NULL, /* readdir */ + NULL, /* select */ + NULL, /* ioctl */ + NULL, /* open */ + NULL /* release */ }; #endif +static struct file_operations null_fops = { + null_lseek, /* lseek */ + null_read, /* read */ + null_write, /* write */ + NULL, /* readdir */ + NULL, /* select */ + NULL, /* ioctl */ + NULL, /* open */ + NULL /* release */ +}; + static struct file_operations zero_fops = { - memory_lseek, /* lseek */ - zero_read, /* read */ - null_write, /* write */ - NULL, /* readdir */ - NULL, /* select */ - NULL, /* ioctl */ - NULL, /* open */ - NULL /* release */ + memory_lseek, /* lseek */ + zero_read, /* read */ + null_write, /* write */ + NULL, /* readdir */ + NULL, /* select */ + NULL, /* ioctl */ + NULL, /* open */ + NULL /* release */ }; static struct file_operations kmem_fops = { - memory_lseek, /* lseek */ - kmem_read, /* read */ - kmem_write, /* write */ - NULL, /* readdir */ - NULL, /* select */ - kmem_ioctl, /* ioctl */ - NULL, /* open */ - NULL /* release */ + memory_lseek, /* lseek */ + kmem_read, /* read */ + kmem_write, /* write */ + NULL, /* readdir */ + NULL, /* select */ + kmem_ioctl, /* ioctl */ + NULL, /* open */ + NULL /* release */ }; -#if UNUSED -static struct file_operations full_fops = { - memory_lseek, /* lseek */ - full_read, /* read */ - full_write, /* write */ - NULL, /* readdir */ - NULL, /* select */ - NULL, /* ioctl */ - NULL, /* open */ - NULL /* release */ -}; +static struct file_operations *mdev_fops[] = { + NULL, + &kmem_fops, /* DEV_MEM_MINOR */ + &kmem_fops, /* DEV_KMEM_MINOR */ + &null_fops, /* DEV_NULL_MINOR */ +#if defined(CONFIG_CHAR_DEV_MEM_PORT_READ) || defined(CONFIG_CHAR_DEV_MEM_PORT_WRITE) + &port_fops, /* DEV_PORT_MINOR */ +#else + NULL, #endif + &zero_fops, /* DEV_ZERO_MINOR */ +}; /* * memory device open multiplexor */ -int memory_open(register struct inode *inode, struct file *filp) +static int memory_open(struct inode *inode, struct file *filp) { - static struct file_operations *mdev_fops[] = { - NULL, - &kmem_fops, /* DEV_MEM_MINOR */ - &kmem_fops, /* DEV_KMEM_MINOR */ - &null_fops, /* DEV_NULL_MINOR */ -#if defined(CONFIG_CHAR_DEV_MEM_PORT_READ) || defined(CONFIG_CHAR_DEV_MEM_PORT_WRITE) - &port_fops, /* DEV_PORT_MINOR */ -#else - NULL, -#endif - &zero_fops, /* DEV_ZERO_MINOR */ -#if UNUSED - &full_fops /* DEV_FULL_MINOR */ -#endif - }; unsigned int minor; minor = MINOR(inode->i_rdev); - if (minor > 5 || !mdev_fops[minor]) - return -ENXIO; + if (minor > DEV_MAX_MINOR || !mdev_fops[minor]) + return -ENXIO; filp->f_op = mdev_fops[minor]; return 0; } static struct file_operations memory_fops = { - NULL, /* lseek */ - NULL, /* read */ - NULL, /* write */ - NULL, /* readdir */ - NULL, /* select */ - NULL, /* ioctl */ - memory_open, /* open */ - NULL /* release */ + NULL, /* lseek */ + NULL, /* read */ + NULL, /* write */ + NULL, /* readdir */ + NULL, /* select */ + NULL, /* ioctl */ + memory_open, /* open */ + NULL /* release */ }; void INITPROC mem_dev_init(void) diff --git a/elks/arch/i86/mm/malloc.c b/elks/arch/i86/mm/malloc.c index 2c69576a8..c8f40d59b 100644 --- a/elks/arch/i86/mm/malloc.c +++ b/elks/arch/i86/mm/malloc.c @@ -22,7 +22,7 @@ // and to ease the 286 protected mode // whenever that mode comes back one day -static list_s _seg_all; +list_s _seg_all; static list_s _seg_free; @@ -36,10 +36,8 @@ static segment_s * seg_split (segment_s * s1, segext_t size0) // TODO: use pool_alloc segment_s * s2 = (segment_s *) heap_alloc (sizeof (segment_s), HEAP_TAG_SEG); - if (!s2) { - printk ("seg:cannot split:heap full\n"); - return 0; - } + if (!s2) + return 0; // heap_alloc gives heap full message s2->base = s1->base + size0; s2->size = size2; @@ -323,7 +321,7 @@ void INITPROC seg_add(seg_t start, seg_t end) seg->ref_count = 0; seg->pid = 0; - list_insert_before (&_seg_all, &(seg->all)); // add tail + list_insert_before (&_seg_all, &(seg->all)); // add tail list_insert_before (&_seg_free, &(seg->free)); // add tail } } diff --git a/elks/include/linuxmt/mem.h b/elks/include/linuxmt/mem.h index 1051cc623..93d219175 100644 --- a/elks/include/linuxmt/mem.h +++ b/elks/include/linuxmt/mem.h @@ -1,20 +1,21 @@ #ifndef __LINUXMT_MEM_H #define __LINUXMT_MEM_H -#define MEM_GETTEXTSIZ 2 -#define MEM_GETUSAGE 3 -#define MEM_GETTASK 4 -#define MEM_GETDS 5 -#define MEM_GETCS 6 -#define MEM_GETHEAP 7 -#define MEM_GETUPTIME 8 +#define MEM_GETTEXTSIZ 2 +#define MEM_GETUSAGE 3 +#define MEM_GETTASK 4 +#define MEM_GETDS 5 +#define MEM_GETCS 6 +#define MEM_GETHEAP 7 +#define MEM_GETUPTIME 8 #define MEM_GETFARTEXT 9 #define MEM_GETMAXTASKS 10 #define MEM_GETJIFFADDR 11 +#define MEM_GETSEGALL 12 struct mem_usage { - unsigned int free_memory; - unsigned int used_memory; + unsigned int free_memory; + unsigned int used_memory; }; #endif diff --git a/elks/include/linuxmt/mm.h b/elks/include/linuxmt/mm.h index 3fdd61701..0d83aaaec 100644 --- a/elks/include/linuxmt/mm.h +++ b/elks/include/linuxmt/mm.h @@ -56,13 +56,13 @@ int fs_memcmp(const void *,const void *,size_t); segment_s * seg_alloc (segext_t, word_t); void seg_free (segment_s *); - segment_s * seg_get (segment_s *); void seg_put (segment_s *); segment_s * seg_dup (segment_s *); - void seg_free_pid(pid_t pid); +extern list_s _seg_all; + void mm_get_usage (unsigned int * free, unsigned int * used); #endif /* __KERNEL__ */ diff --git a/elkscmd/man/man1/meminfo.1 b/elkscmd/man/man1/meminfo.1 index 05218f402..fd8243530 100644 --- a/elkscmd/man/man1/meminfo.1 +++ b/elkscmd/man/man1/meminfo.1 @@ -4,15 +4,21 @@ meminfo \- list system memory usage .SH SYNOPSIS .B meminfo .RB [ \-a ] +.RB [ \-m ] .RB [ \-f ] .RB [ \-t ] .RB [ \-b ] +.RB [ \-s ] +.RB [ \-h ] .br .SS OPTIONS -Defaults to showing all memory. +Defaults to showing all memory (equivalent to -aftbs). .TP 5 .B -a -Show application memory +Show memory in use by applications +.TP 5 +.B -m +Show main memory sorted by segment .TP 5 .B -f Show free memory @@ -24,7 +30,10 @@ Show tty and driver memory Show system buffer and pipe memory .TP 5 .B -s -Show system task, inode and file memory. +Show system task, inode and file memory +.TP 5 +.B -h +Show help .SH DESCRIPTION .B meminfo traverses the kernel local heap and displays a line for each in-use or free entry. diff --git a/elkscmd/sys_utils/meminfo.c b/elkscmd/sys_utils/meminfo.c index 225ab55c0..6f3c80cca 100644 --- a/elkscmd/sys_utils/meminfo.c +++ b/elkscmd/sys_utils/meminfo.c @@ -28,10 +28,12 @@ int fflag; /* show free memory*/ int tflag; /* show tty and driver memory*/ int bflag; /* show buffer memory*/ int sflag; /* show system memory*/ +int mflag; /* show main memory*/ int allflag; /* show all memory*/ unsigned int ds; unsigned int heap_all; +unsigned int seg_all; unsigned int taskoff; int maxtasks; struct task_struct task_table; @@ -92,15 +94,55 @@ struct task_struct *find_process(int fd, unsigned int seg) return NULL; } +static long total_segsize = 0; +static char *segtype[] = + { "free", "CSEG", "DSEG", "DDAT", "FDAT", "BUF ", "RDSK" }; + +void display_seg(int fd, word_t mem) +{ + seg_t segbase = getword(fd, mem + offsetof(segment_s, base), ds); + segext_t segsize = getword(fd, mem + offsetof(segment_s, size), ds); + word_t segflags = getword(fd, mem + offsetof(segment_s, flags), ds) & SEG_FLAG_TYPE; + byte_t ref_count = getword(fd, mem + offsetof(segment_s, ref_count), ds); + struct task_struct *t; + + printf(" %4x %s %7ld %4d ", + segbase, segtype[segflags], (long)segsize << 4, ref_count); + if (segflags == SEG_FLAG_CSEG || segflags == SEG_FLAG_DSEG) { + if ((t = find_process(fd, mem)) != NULL) { + process_name(fd, t->t_begstack, t->t_regs.ss); + } + } + + total_segsize += (long)segsize << 4; +} + +void dump_segs(int fd) +{ + word_t n, mem; + seg_t segbase, oldbase = 0; + + printf(" SEG TYPE SIZE CNT NAME\n"); + n = getword (fd, seg_all + offsetof(list_s, next), ds); + while (n != seg_all) { + mem = n - offsetof(segment_s, all); + segbase = getword(fd, mem + offsetof(segment_s, base), ds); + if (segbase < oldbase) printf("\n"); + oldbase = segbase; + display_seg(fd, mem); + printf("\n"); + + /* next in list */ + n = getword(fd, n + offsetof(list_s, next), ds); + } +} + void dump_heap(int fd) { word_t total_size = 0; word_t total_free = 0; - long total_segsize = 0; static char *heaptype[] = { "free", "MEM ", "DRVR", "TTY ", "TASK", "BUFH", "PIPE", "INOD", "FILE", "CACH"}; - static char *segtype[] = - { "free", "CSEG", "DSEG", "DDAT", "FDAT", "BUF ", "RDSK" }; printf(" HEAP TYPE SIZE SEG TYPE SIZE CNT NAME\n"); @@ -110,18 +152,14 @@ void dump_heap(int fd) word_t size = getword(fd, h + offsetof(heap_s, size), ds); byte_t tag = getword(fd, h + offsetof(heap_s, tag), ds) & HEAP_TAG_TYPE; word_t mem = h + sizeof(heap_s); - seg_t segbase; - segext_t segsize; word_t segflags; - byte_t ref_count; - int free, used, tty, buffer, system; - struct task_struct *t; + int free, app, tty, buffer, system; if (tag == HEAP_TAG_SEG) segflags = getword(fd, mem + offsetof(segment_s, flags), ds) & SEG_FLAG_TYPE; else segflags = -1; free = (tag == HEAP_TAG_FREE || segflags == SEG_FLAG_FREE); - used = ((tag == HEAP_TAG_SEG) + app = ((tag == HEAP_TAG_SEG) && (segflags == SEG_FLAG_CSEG || segflags == SEG_FLAG_DSEG || segflags == SEG_FLAG_DDAT || segflags == SEG_FLAG_FDAT)); tty = (tag == HEAP_TAG_TTY || tag == HEAP_TAG_DRVR); @@ -129,9 +167,8 @@ void dump_heap(int fd) || tag == HEAP_TAG_BUFHEAD || tag == HEAP_TAG_CACHE || tag == HEAP_TAG_PIPE; system = (tag == HEAP_TAG_TASK || tag == HEAP_TAG_INODE || tag == HEAP_TAG_FILE); - if (allflag || - (fflag && free) || (aflag && used) || (tflag && tty) || (bflag && buffer) - || (sflag && system)) { + if (allflag || (fflag && free) || (aflag && app) || (tflag && tty) + || (bflag && buffer) || (sflag && system)) { printf(" %4x %s %5d", mem, heaptype[tag], size); total_size += size + sizeof(heap_s); if (tag == HEAP_TAG_FREE) @@ -139,18 +176,7 @@ void dump_heap(int fd) switch (tag) { case HEAP_TAG_SEG: - segbase = getword(fd, mem + offsetof(segment_s, base), ds); - segsize = getword(fd, mem + offsetof(segment_s, size), ds); - ref_count = getword(fd, mem + offsetof(segment_s, ref_count), ds); - printf(" %4x %s %7ld %4d ", - segbase, segtype[segflags], (long)segsize << 4, ref_count); - if (segflags == SEG_FLAG_CSEG || segflags == SEG_FLAG_DSEG) { - if ((t = find_process(fd, mem)) != NULL) { - process_name(fd, t->t_begstack, t->t_regs.ss); - } - } - - total_segsize += (long)segsize << 4; + display_seg(fd, mem); break; } printf("\n"); @@ -165,7 +191,7 @@ void dump_heap(int fd) void usage(void) { - printf("usage: meminfo [-a][-f][-t][-b]\n"); + printf("usage: meminfo [-amftbsh]\n"); } int main(int argc, char **argv) @@ -175,11 +201,14 @@ int main(int argc, char **argv) if (argc < 2) allflag = 1; - else while ((c = getopt(argc, argv, "aftbsh")) != -1) { + else while ((c = getopt(argc, argv, "amftbsh")) != -1) { switch (c) { case 'a': aflag = 1; break; + case 'm': + mflag = 1; + break; case 'f': fflag = 1; break; @@ -207,15 +236,18 @@ int main(int argc, char **argv) } if (ioctl(fd, MEM_GETDS, &ds) || ioctl(fd, MEM_GETHEAP, &heap_all) || + ioctl(fd, MEM_GETSEGALL, &seg_all) || ioctl(fd, MEM_GETTASK, &taskoff) || ioctl(fd, MEM_GETMAXTASKS, &maxtasks)) { perror("meminfo"); - return 1; + return 1; } if (!memread(fd, taskoff, ds, &task_table, sizeof(task_table))) { perror("taskinfo"); } - dump_heap(fd); + if (mflag) + dump_segs(fd); + else dump_heap(fd); if (!ioctl(fd, MEM_GETUSAGE, &mu)) { /* note MEM_GETUSAGE amounts are floors, so total may display less by 1k than actual*/