Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ UPROGS=\
$U/_mkdir\
$U/_rm\
$U/_sh\
$U/_sleep\
$U/_stressfs\
$U/_usertests\
$U/_grind\
Expand All @@ -145,6 +146,7 @@ UPROGS=\
$U/_logstress\
$U/_forphan\
$U/_dorphan\
$U/_ps\

fs.img: mkfs/mkfs README $(UPROGS)
mkfs/mkfs fs.img README $(UPROGS)
Expand Down
1 change: 1 addition & 0 deletions kernel/defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ void sched(void);
void sleep(void*, struct spinlock*);
void userinit(void);
int kwait(uint64);
int kps(uint64, int);
void wakeup(void*);
void yield(void);
int either_copyout(int user_dst, uint64 dst, void *src, uint64 len);
Expand Down
38 changes: 38 additions & 0 deletions kernel/proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "riscv.h"
#include "spinlock.h"
#include "proc.h"
#include "ps.h"
#include "defs.h"

struct cpu cpus[NCPU];
Expand Down Expand Up @@ -688,3 +689,40 @@ procdump(void)
printf("\n");
}
}

// Copy process info to userspace.
// Iterate through proc table and copy RUNNABLE/RUNNING/SLEEPING processes.
// Returns number of processes copied, or -1 on error.
int
kps(uint64 addr, int max)
{
if(max < 0 || max > 256)
return -1;

struct proc *cur = myproc();
struct proc *p;
int n = 0;

for(p = proc; p < &proc[NPROC] && n < max; p++){
struct pinfo pi;
int include = 0;

acquire(&p->lock);
if(p->state == SLEEPING || p->state == RUNNABLE || p->state == RUNNING){
pi.pid = p->pid;
pi.state = p->state;
pi.sz = p->sz;
safestrcpy(pi.name, p->name, sizeof(pi.name));
include = 1;
}
release(&p->lock);

if(include){
if(copyout(cur->pagetable, addr + n * sizeof(pi), (char *)&pi, sizeof(pi)) < 0)
return -1;
n++;
}
}

return n;
}
18 changes: 18 additions & 0 deletions kernel/ps.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#ifndef _KERNEL_PS_H_
#define _KERNEL_PS_H_

#define PS_NAME_LEN 16

// Matches enum procstate in proc.h
#define PS_SLEEPING 2
#define PS_RUNNABLE 3
#define PS_RUNNING 4

struct pinfo {
int pid;
int state;
uint64 sz;
char name[PS_NAME_LEN];
};

#endif
2 changes: 2 additions & 0 deletions kernel/syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ extern uint64 sys_unlink(void);
extern uint64 sys_link(void);
extern uint64 sys_mkdir(void);
extern uint64 sys_close(void);
extern uint64 sys_ps(void);

// An array mapping syscall numbers from syscall.h
// to the function that handles the system call.
Expand All @@ -126,6 +127,7 @@ static uint64 (*syscalls[])(void) = {
[SYS_link] sys_link,
[SYS_mkdir] sys_mkdir,
[SYS_close] sys_close,
[SYS_ps] sys_ps,
};

void
Expand Down
1 change: 1 addition & 0 deletions kernel/syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@
#define SYS_link 19
#define SYS_mkdir 20
#define SYS_close 21
#define SYS_ps 22
11 changes: 11 additions & 0 deletions kernel/sysproc.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,17 @@ sys_wait(void)
return kwait(p);
}

uint64
sys_ps(void)
{
uint64 p;
int max;

argaddr(0, &p);
argint(1, &max);
return kps(p, max);
}

uint64
sys_sbrk(void)
{
Expand Down
39 changes: 39 additions & 0 deletions user/ps.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#include "kernel/types.h"
#include "kernel/ps.h"
#include "user/user.h"

#define MAX_PROCS 64

static char *
state_name(int s)
{
switch(s){
case PS_SLEEPING:
return "sleep";
case PS_RUNNABLE:
return "runnable";
case PS_RUNNING:
return "running";
default:
return "?";
}
}

int
main(void)
{
struct pinfo list[MAX_PROCS];
int n = ps(list, MAX_PROCS);

if(n < 0){
fprintf(2, "ps: syscall failed\n");
exit(1);
}

printf("PID\tSTATE\t\tSIZE(KB)\tNAME\n");
for(int i = 0; i < n; i++){
printf("%d\t%s\t\t%ld\t\t%s\n", list[i].pid, state_name(list[i].state), list[i].sz / 1024, list[i].name);
}

exit(0);
}
18 changes: 18 additions & 0 deletions user/sleep.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include "kernel/types.h"
#include "user/user.h"

int
main(int argc, char *argv[])
{
int i;

if(argc < 2){
fprintf(2, "usage: sleep seconds\n");
exit(1);
}
i = atoi(argv[1]);
if(i < 0)
i = 0;
pause(i * 100);
exit(0);
}
2 changes: 2 additions & 0 deletions user/user.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#define SBRK_ERROR ((char *)-1)

struct pinfo;
struct stat;

// system calls
Expand All @@ -24,6 +25,7 @@ int getpid(void);
char* sys_sbrk(int,int);
int pause(int);
int uptime(void);
int ps(struct pinfo*, int);

// ulib.c
int stat(const char*, struct stat*);
Expand Down
1 change: 1 addition & 0 deletions user/usys.pl
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,4 @@ sub entry {
entry("sbrk");
entry("pause");
entry("uptime");
entry("ps");