Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tarea 2 #176

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
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
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ OBJS = \
uart.o\
vectors.o\
vm.o\
rand.o\

# Cross-compiling (e.g., on Mac OS X)
# TOOLPREFIX = i386-jos-elf
Expand Down
57 changes: 43 additions & 14 deletions proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "x86.h"
#include "proc.h"
#include "spinlock.h"
#include "rand.h"

struct {
struct spinlock lock;
Expand Down Expand Up @@ -70,16 +71,17 @@ myproc(void) {
// If found, change state to EMBRYO and initialize
// state required to run in the kernel.
// Otherwise return 0.
static struct proc*
static struct proc *
allocproc(void)
{
struct proc *p;
char *sp;
static int count = 0;

acquire(&ptable.lock);

for(p = ptable.proc; p < &ptable.proc[NPROC]; p++)
if(p->state == UNUSED)
for (p = ptable.proc; p < &ptable.proc[NPROC]; p++)
if (p->state == UNUSED)
goto found;

release(&ptable.lock);
Expand All @@ -88,27 +90,29 @@ allocproc(void)
found:
p->state = EMBRYO;
p->pid = nextpid++;
p->tickets = count++ + (nextpid * 10) / 5;

release(&ptable.lock);

// Allocate kernel stack.
if((p->kstack = kalloc()) == 0){
if ((p->kstack = kalloc()) == 0)
{
p->state = UNUSED;
return 0;
}
sp = p->kstack + KSTACKSIZE;

// Leave room for trap frame.
sp -= sizeof *p->tf;
p->tf = (struct trapframe*)sp;
p->tf = (struct trapframe *)sp;

// Set up new context to start executing at forkret,
// which returns to trapret.
sp -= 4;
*(uint*)sp = (uint)trapret;
*(uint *)sp = (uint)trapret;

sp -= sizeof *p->context;
p->context = (struct context*)sp;
p->context = (struct context *)sp;
memset(p->context, 0, sizeof *p->context);
p->context->eip = (uint)forkret;

Expand Down Expand Up @@ -319,22 +323,47 @@ wait(void)
// - swtch to start running that process
// - eventually that process transfers control
// via swtch back to the scheduler.
void
scheduler(void)
void scheduler(void)
{
struct proc *p;
struct cpu *c = mycpu();
c->proc = 0;

for(;;){

for (;;)
{
// Enable interrupts on this processor.
sti();

int tickets_passed = 0;
int number_tickets = 0;

//cuenta el total de tickets
for (p = ptable.proc; p < &ptable.proc[NPROC]; p++)
{
if (p->state != RUNNABLE)
continue;
number_tickets = number_tickets + p->tickets;
}

long winner = random_tickets(number_tickets );

// Loop over process table looking for process to run.
acquire(&ptable.lock);
for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){
if(p->state != RUNNABLE)
for (p = ptable.proc; p < &ptable.proc[NPROC]; p++)
{
if (p->state != RUNNABLE)
continue;
tickets_passed += p->tickets;
if (tickets_passed < winner)
{
continue;
}
if (tickets_passed == winner) //Estas 3 lineas eran para verificar que funcionaba el Lottery Scheduler
{
cprintf("\t\tTickets Passed: %d\n", tickets_passed);
cprintf("\t\tProcess Winner: %s\n", p->name);
cprintf("\t\tProcess Tickets: %d\n", p->tickets);
}

// Switch to chosen process. It is the process's job
// to release ptable.lock and then reacquire it
Expand All @@ -349,9 +378,9 @@ scheduler(void)
// Process is done running for now.
// It should have changed its p->state before coming back.
c->proc = 0;
break;
}
release(&ptable.lock);

}
}

Expand Down
3 changes: 2 additions & 1 deletion proc.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ struct proc {
int killed; // If non-zero, have been killed
struct file *ofile[NOFILE]; // Open files
struct inode *cwd; // Current directory
char name[16]; // Process name (debugging)
char name[16];
int tickets; // Process name (debugging)
};

// Process memory is laid out contiguously, low addresses first:
Expand Down
120 changes: 120 additions & 0 deletions rand.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/* A C-program for MT19937: Real number version */
/* genrand() generates one pseudorandom real number (double) */
/* which is uniformly distributed on [0,1]-interval, for each */
/* call. sgenrand(seed) set initial values to the working area */
/* of 624 words. Before genrand(), sgenrand(seed) must be */
/* called once. (seed is any 32-bit integer except for 0). */
/* Integer generator is obtained by modifying two lines. */
/* Coded by Takuji Nishimura, considering the suggestions by */
/* Topher Cooper and Marc Rieffel in July-Aug. 1997. */

/* This library is free software; you can redistribute it and/or */
/* modify it under the terms of the GNU Library General Public */
/* License as published by the Free Software Foundation; either */
/* version 2 of the License, or (at your option) any later */
/* version. */
/* This library is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */
/* See the GNU Library General Public License for more details. */
/* You should have received a copy of the GNU Library General */
/* Public License along with this library; if not, write to the */
/* Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA */
/* 02111-1307 USA */

/* Copyright (C) 1997 Makoto Matsumoto and Takuji Nishimura. */
/* Any feedback is very welcome. For any question, comments, */
/* see http://www.math.keio.ac.jp/matumoto/emt.html or email */
/* matumoto@math.keio.ac.jp */

/* Period parameters */
#define N 624
#define M 397
#define MATRIX_A 0x9908b0df /* constant vector a */
#define UPPER_MASK 0x80000000 /* most significant w-r bits */
#define LOWER_MASK 0x7fffffff /* least significant r bits */

/* Tempering parameters */
#define TEMPERING_MASK_B 0x9d2c5680
#define TEMPERING_MASK_C 0xefc60000
#define TEMPERING_SHIFT_U(y) (y >> 11)
#define TEMPERING_SHIFT_S(y) (y << 7)
#define TEMPERING_SHIFT_T(y) (y << 15)
#define TEMPERING_SHIFT_L(y) (y >> 18)

#define RAND_MAX 0x7fffffff

static unsigned long mt[N]; /* the array for the state vector */
static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */

/* initializing the array with a NONZERO seed */
void
sgenrand(unsigned long seed)
{
/* setting initial seeds to mt[N] using */
/* the generator Line 25 of Table 1 in */
/* [KNUTH 1981, The Art of Computer Programming */
/* Vol. 2 (2nd Ed.), pp102] */
mt[0]= seed & 0xffffffff;
for (mti=1; mti<N; mti++)
mt[mti] = (69069 * mt[mti-1]) & 0xffffffff;
}

long /* for integer generation */
genrand()
{
unsigned long y;
static unsigned long mag01[2]={0x0, MATRIX_A};
/* mag01[x] = x * MATRIX_A for x=0,1 */

if (mti >= N) { /* generate N words at one time */
int kk;

if (mti == N+1) /* if sgenrand() has not been called, */
sgenrand(4357); /* a default initial seed is used */

for (kk=0;kk<N-M;kk++) {
y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1];
}
for (;kk<N-1;kk++) {
y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1];
}
y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1];

mti = 0;
}

y = mt[mti++];
y ^= TEMPERING_SHIFT_U(y);
y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B;
y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C;
y ^= TEMPERING_SHIFT_L(y);

// Strip off uppermost bit because we want a long,
// not an unsigned long
return y & RAND_MAX;
}

// Assumes 0 <= max <= RAND_MAX
// Returns in the half-open interval [0, max]
long random_tickets(long max) {
unsigned long
// max <= RAND_MAX < ULONG_MAX, so this is okay.
num_bins = (unsigned long) max + 1,
num_rand = (unsigned long) RAND_MAX + 1,
bin_size = num_rand / num_bins,
defect = num_rand % num_bins;

long x;
do {
x = genrand();
}
// This is carefully written not to overflow
while (num_rand - defect <= (unsigned long)x);

// Truncated division is intentional
return x/bin_size;
}
3 changes: 3 additions & 0 deletions rand.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
void sgenrand(unsigned long);
long genrand(void);
long random_tickets(long);
1 change: 1 addition & 0 deletions syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ static int (*syscalls[])(void) = {
void
syscall(void)
{

int num;
struct proc *curproc = myproc();

Expand Down