Skip to content

Commit

Permalink
Merge pull request #1 from Make-IT-Wright/implement_ps
Browse files Browse the repository at this point in the history
Implement ps
  • Loading branch information
Make-IT-Wright authored Mar 20, 2023
2 parents a02bda3 + 498cab6 commit 69cb5b1
Show file tree
Hide file tree
Showing 10 changed files with 132 additions and 17 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ UPROGS=\
_mycat2\
_snprintftest\
_ps\
_longRunner\

fs.img: mkfs README $(UPROGS)
./mkfs fs.img README $(UPROGS)
Expand Down
12 changes: 11 additions & 1 deletion defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,17 @@ void switchkvm(void);
int copyout(pde_t*, uint, void*, uint);
void clearpteu(pde_t *pgdir, char *uva);

int proc_ps(int);
struct procInfo;

/// @brief Call this function to obtain information about existing
/// processes.
/// @param count : the maximum number of elements storable in procInfoArray
/// @param procInfoArray : an array of struct procInfo able to store at least
/// count elements.
/// @return The number of struct procInfo structures stored in procInfoArray
/// by the kernel. This number may be less than count, and if it is, elements
/// at indexes >= count may contain uninitialized memory.
int proc_ps(int count, struct procInfo* procInfoArray);

// number of elements in fixed-size array
#define NELEM(x) (sizeof(x)/sizeof((x)[0]))
24 changes: 24 additions & 0 deletions longRunner.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include "types.h"
#include "stat.h"
#include "user.h"

static volatile int counter = 0;

int loop(int n)
{
for(int i = n * 4096; i > 0; --i) {
for(int j = n * 4096; j > 0; --j) {
counter += 1;
}
}
return counter;
}

int
main(int argc, char *argv[])
{
for(int j = 3; j > 0; --j) {
loop(j);
}
exit();
}
4 changes: 4 additions & 0 deletions param.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
#ifndef PARAM_H
#define PARAM_H

#define NPROC 64 // maximum number of processes
#define KSTACKSIZE 4096 // size of per-process kernel stack
#define NCPU 8 // maximum number of CPUs
Expand All @@ -12,3 +15,4 @@
#define NBUF (MAXOPBLOCKS*3) // size of disk block cache
#define FSSIZE 2000 // size of file system in blocks

#endif // PARAM_H
44 changes: 33 additions & 11 deletions proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@
#include "proc.h"
#include "spinlock.h"

static const char * const states[] = {
[UNUSED] "unused",
[EMBRYO] "embryo",
[SLEEPING] "sleep ",
[RUNNABLE] "runble",
[RUNNING] "run ",
[ZOMBIE] "zombie"
};

struct {
struct spinlock lock;
struct proc proc[NPROC];
Expand All @@ -20,21 +29,37 @@ extern void trapret(void);

static void wakeup1(void *chan);

int proc_ps(int numberOfProcs)
int proc_ps(int numberOfProcs, struct procInfo* arrayOfProcInfo)
{
struct proc *p;
int result = 0;
int procInfoArrayIndex = 0;
int currentTicks = ticks;

acquire(&ptable.lock);

for(p = ptable.proc; p < &ptable.proc[NPROC]; p++) {
if(p->state != UNUSED) {
safestrcpy(arrayOfProcInfo[procInfoArrayIndex].name, p->name,
MAX_PROC_NAME_LENGTH);
arrayOfProcInfo[procInfoArrayIndex].pid = p->pid;
arrayOfProcInfo[procInfoArrayIndex].state = p->state;
int elapsedTicks = currentTicks - p->ticksAtStart;
int cpuPercent = 0;
if(elapsedTicks > 0 && 1 < p->ticksScheduled) {
cpuPercent = (p->ticksScheduled * 100) / elapsedTicks;
if(100 < cpuPercent) {
cpuPercent = 100;
}
}
arrayOfProcInfo[procInfoArrayIndex].cpuPercent = cpuPercent;
++procInfoArrayIndex;
++result;
}
}

release(&ptable.lock);
return result + numberOfProcs;
return procInfoArrayIndex;
}

void
Expand Down Expand Up @@ -158,6 +183,8 @@ userinit(void)

safestrcpy(p->name, "initcode", sizeof(p->name));
p->cwd = namei("/");
p->ticksAtStart = ticks;
p->ticksScheduled = 0;

// this assignment to p->state lets other cores
// run this process. the acquire forces the above
Expand Down Expand Up @@ -232,6 +259,8 @@ fork(void)
acquire(&ptable.lock);

np->state = RUNNABLE;
np->ticksAtStart = ticks;
np->ticksScheduled = 0;

release(&ptable.lock);

Expand Down Expand Up @@ -394,6 +423,7 @@ sched(void)
if(readeflags()&FL_IF)
panic("sched interruptible");
intena = mycpu()->intena;
p->ticksScheduled += 1;
swtch(&p->context, mycpu()->scheduler);
mycpu()->intena = intena;
}
Expand Down Expand Up @@ -520,17 +550,9 @@ kill(int pid)
void
procdump(void)
{
static char *states[] = {
[UNUSED] "unused",
[EMBRYO] "embryo",
[SLEEPING] "sleep ",
[RUNNABLE] "runble",
[RUNNING] "run ",
[ZOMBIE] "zombie"
};
int i;
struct proc *p;
char *state;
const char *state;
uint pc[10];

for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){
Expand Down
6 changes: 5 additions & 1 deletion proc.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
#include "param.h"
#include "types.h"

// Per-CPU state
struct cpu {
uchar apicid; // Local APIC ID
Expand Down Expand Up @@ -32,7 +35,6 @@ struct context {
uint eip;
};

enum procstate { UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE };

// Per-process state
struct proc {
Expand All @@ -49,6 +51,8 @@ struct proc {
struct file *ofile[NOFILE]; // Open files
struct inode *cwd; // Current directory
char name[16]; // Process name (debugging)
int ticksAtStart;
int ticksScheduled;
};

// Process memory is laid out contiguously, low addresses first:
Expand Down
19 changes: 17 additions & 2 deletions ps.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,25 @@
#include "stat.h"
#include "user.h"

static struct procInfo arrayOfProcInfo[1024];
static const char * const states[] = {
[UNUSED] "unused",
[EMBRYO] "embryo",
[SLEEPING] "sleep ",
[RUNNABLE] "ready ",
[RUNNING] "run ",
[ZOMBIE] "zombie"
};

int
main(int argc, char *argv[])
{
int result = ps(-99);
printf(1, "ps returned <%d>!\n", result);
int result = ps(1024, arrayOfProcInfo);
for(int i = 0; i < result; ++i) {
printf(1, "%d: %s %d %s\n", arrayOfProcInfo[i].pid,
states[arrayOfProcInfo[i].state],
arrayOfProcInfo[i].cpuPercent,
arrayOfProcInfo[i].name);
}
exit();
}
13 changes: 12 additions & 1 deletion sysproc.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,22 @@ int sys_shutdown(void)
return 0;
}

/// @brief This is the kernel side of a system call to obtain information
/// about existing processes in the kernel
/// arg0 is the maximum number of elements storable in procInfoArray
/// arg1 is an array of struct procInfo able to store at least
/// arg0 elements.
/// @return The number of struct procInfo structures stored in arg1.
/// This number may be less than arg0, and if it is, elements
/// at indexes >= arg0 may contain uninitialized memory.
int sys_ps(void)
{
int numberOfProcs;
struct procInfo* procInfoArray;

if(argint(0, &numberOfProcs) < 0)
return -1;
return proc_ps(numberOfProcs);
if(argptr(1, (char **)&procInfoArray, sizeof(struct procInfo *)) < 0)
return -1;
return proc_ps(numberOfProcs, procInfoArray);
}
15 changes: 15 additions & 0 deletions types.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,19 @@
#ifndef TYPES_H
#define TYPES_H

typedef unsigned int uint;
typedef unsigned short ushort;
typedef unsigned char uchar;
typedef uint pde_t;

enum procstate { UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE };

#define MAX_PROC_NAME_LENGTH (16)
struct procInfo {
int state;
int pid;
int cpuPercent;
char name[MAX_PROC_NAME_LENGTH];
};

#endif // TYPES_H
11 changes: 10 additions & 1 deletion user.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,16 @@ int sleep(int);
int uptime(void);
int yield(void);
int shutdown(void);
int ps(int);

/// @brief This is a system call to obtain information about existing
/// processes in the kernel
/// @param count : the maximum number of elements storable in procInfoArray
/// @param procInfoArray : an array of struct procInfo able to store at least
/// count elements.
/// @return The number of struct procInfo structures stored in procInfoArray
/// by the kernel. This number may be less than count, and if it is, elements
/// at indexes >= count may contain uninitialized memory.
int ps(int count, struct procInfo* procInfoArray);

// ulib.c
int stat(const char*, struct stat*);
Expand Down

0 comments on commit 69cb5b1

Please sign in to comment.