Kernel Module Programming Kernel Modules, Mutual Exclusion, and Scheduling

code is already there only edit some parts 

Save Time On Research and Writing
Hire a Pro to Write You a 100% Plagiarism-Free Paper.
Get My Paper

__MACOSX/._untitled folder 2

untitled folder 2/project3

Project 3 Specification
Kernel Module Programming

Kernel Modules, Mutual Exclusion, and Scheduling

Save Time On Research and Writing
Hire a Pro to Write You a 100% Plagiarism-Free Paper.
Get My Paper

Final Submission Due: 3/27 at 11:59:59pm

Language Restrictions: C only

Purpose

This project introduces you to the nuts and bolts of kernel programming, concurrency, and
synchronization in the kernel. This project is divided into two parts and worth 40 points. This project
may be completed in partners or by yourself.

Part 1: remember Kernel Module

In Unix-like operating systems, the /proc interface is often used to set or read kernel information. For
example, take a look at /proc/cpuinfo and /proc/meminfo using the following commands:

$> cat /proc/cpuinfo

$> cat /proc/meminfo

Even though these proc files look like ordinary files, they are actually virtual kernel drivers! These
modules perform actions based on whether a user reads or writes to them.

You will write your own proc module called remember that

1. allows the user to write a string (max length 80)
2. allows the user to read back the string that was just added

For example:
$> echo “Hello there” > /proc/remember
$> cat /proc/remember
Hello there
$>

Please use the example proc module (hello_proc.c) and Makefile provided to you as a starting point.
Change the name of the module from helloworld to remember, create a global string of size 80 to hold
the string written, and use that global variable whenever a read is performed.

You can use the original 4.9 kernel or the 5.5.5 kernel.

Part 2: Your very own Virtual Printer

Congratulations, you are the proud owner of a new virtual printer called the penguin printer (a.k.a
“penguin”). Your task is to implement a printer scheduling algorithm. A printer is defined as a device
that accepts print jobs for documents into a queue and processes those documents. A maximum
number of jobs will be given. When a printer is loaded, it is initially running. Each job takes a specific

amount of time to process. Finally, the printer is stopped when the module is unloaded.

Your printer must keep track of the number and type of jobs in a queue. Jobs can come in at any time
and can be put on the queue instantaneously. A job must always be accepted if there is room. Jobs can
only be processed by the printer one at a time, and it takes the printer 1 second to look inside any spot
in the queue (whether it holds a job or not). Once a job is processed, the spot in the queue is cleared
and the printer can look for other jobs.

Task Specification

This is a classic exercise in modeling consumers and producers. The producer produces jobs and the
consumer is the printer. There are many pieces needed to provide a complete implementation discussed
below.

Step 1: Develop a penguin printer /proc module
Develop a /proc entry named /proc/penguin. In this project, you will be required to support a
printer job queue of size 10. You will accept the following 4 jobs:

• 1-page document (internally represented with a 1)
• 2-page document (internally represented with a 2)
• 3-page document (internally represented with a 3)
• 4-page document (internally represented with a 4)

As in a real printer, it takes varying time to process different types of jobs. Your printer must take 1
second to process a 1-page document, 2 seconds to process a 2-page document, 3 seconds to process a
3-page document, and 4 seconds to process a 4-page document. This processing time is in addition to
the 1 second it must take to look in any spot in the queue for an job.

Finally, the printer can break down. It also must accept the following job:

• maintenance (internally represented with a 5)

Maintenance takes a whopping 10 seconds, in addition to the 1 second it must take to look in any spot
in the queue for a job.

(Hint – you can “process” for a given amount of seconds by using the ssleep() function.)

You will place jobs on your queue by writing your jobs’s number to the /proc/penguin file. For
example, the following will put a 2-page document on the order queue:

$> echo 2 > /proc/penguin

If the queue is full, the printer code should return –ENOMEM and the job should not be placed on the
queue.

$> echo 2 > /proc/penguin
bash: echo: write error: Cannot allocate memory

Step 2: Reading from /proc/ penguin

In addition to accepting orders and commands, your printer must be able to display status information
by reading the device. Specifically, when someone reads from /proc/penguin, they should see:

• Current spot being looked at in the queue
• Current job being processed
• Total jobs processed

For example, take a look at this sample session:
$> insmod penguin.ko
$> cat /proc/penguin
Processing nothing at slot 2. Total jobs processed: 0.
$> echo 4 > /proc/penguin
$> cat /proc/penguin
Processing nothing at slot 8. Total jobs processed: 0.
$> cat /proc/penguin
PriProcessing 4-page document at slot 0. Total jobs processed: 0.
$> cat /proc/penguin
Processing 4-page document at slot 0. Total jobs processed: 0.
$> cat /proc/penguin
Processing nothing at slot 2. Total jobs processed: 1.
$> rmmod penguin

The insmod and rmmod commands load and unload the kernel module, respectively. After starting the
printer, I placed 4-page document on the queue. However, when immediately reading from
/proc/penguin, my printer was not yet looking in the spot in the queue with the 4-page document.
Finally, it looks in the right spot and “processes” the 4-page for 4 seconds, so I was able to read from
/proc/penguin twice and get the same processing status.

Step 3: Use a kthread

You must use a kthread to allow the printer to run in the background and process orders. Please look at
my example, which starts a kthread on module load.

Step 4: Mutual Exclusion

You may have been getting lucky up until now, but what happens if the printer kthread is modifying a
spot in your job queue that you are trying to read at the same time? What happens if you are trying to
add a job to the queue at the same time that the printer is taking one away? If you have any global
variables in your code that can be accessed by more than one thread at a time, you must protect the
reading and writing of those variables with mutexes (semaphores with only 0 and 1 values). If not,
your entire driver could randomly crash. The probability of this goes up with the more cores you have
in your virtual machine. Use kernel mutexes to protect critical sections of code where you read or
write to global variables.

Extra Credit

The top five submissions as measured by the above evaluation procedure will receive +5 points to their
project 3 grade. The metric to optimize is: total jobs processed.

Full Project Submission Procedure

You will need to submit the following files:

• remember.c (not the .ko or the Makefile)
• penguin.c (not the .ko or the Makefile)
• The filled-in Project3-README x. (If you are a Mac user, please keep the format as Word or

else convert to a pdf. I have problems grading Pages documents on a non-Mac.)

__MACOSX/untitled folder 2/._project3

untitled folder 2/watch_syslog.sh
#!/bin/bash
tail -f /var/log/syslog

__MACOSX/untitled folder 2/._watch_syslog.sh

untitled folder 2/penguin.c
#include #include #include #include #include #include #include #include

MODULE_LICENSE(“GPL”); /* Kernel needs this license. */
#define ENTRY_NAME “penguin”
#define PERMS 0644
#define PARENT NULL
/* Function declarations */
ssize_t procfile_read(struct file *filp, char __user *buf, size_t count,
loff_t *f_pos);
ssize_t procfile_write(struct file *filp, const char __user *buf, size_t count,
loff_t *f_pos);
static int t_penguin(void* data);
/* Global variables go here */
static struct file_operations hello_proc_ops = {
.owner = THIS_MODULE,
.read = procfile_read,
.write = procfile_write,
};
struct task_struct *t; /* Printer thread task struct (use to start/stop)*/

/* The kitchen thread will run this function. The thread will stop
* when either kitchen_stop(t) is called or else the function ends. */
static int t_penguin(void* data) {
int i=0;
/* Print hello 50 times, then stop on it’s own */
while(!kthread_should_stop()) {
printk(“Hello from the penguin! Run %i\n”, i);
/* Sleep one second */
ssleep(1);
i++;
}
return 0;
}

int hello_proc_init(void) {
proc_create_data(ENTRY_NAME, 0, NULL, &hello_proc_ops, NULL);

/* This message will print in /var/log/syslog or on the first tty. */
printk(“/proc/%s created\n”, ENTRY_NAME);
/* Start the printer — move out of here later. */
t = kthread_run(t_penguin, NULL, “penguin_thread”);

return 0;
}
ssize_t procfile_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
static int finished = 0;
int ret;
char ret_buf[80];
/* Are we done reading? If so, we return 0 to indicate end-of-file */
if (finished) {
finished=0;
return 0;
}
finished = 1;
/* This message will print in /var/log/syslog or on the first tty. */
printk(“/proc/%s read called.\n”, ENTRY_NAME);
ret=sprintf(ret_buf, “Penguin read called.\n”);
if(copy_to_user(buf, ret_buf, ret)) {
ret = -EFAULT;
}
return ret;
}
ssize_t procfile_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{
char *page; /* don’t touch */
int my_data = 0;

/* Allocating kernel memory, don’t touch. */
page = (char *) vmalloc(count);
if (!page)
return -ENOMEM;
/* Copy the data from the user space. Data is placed in page. */
if (copy_from_user(page, buf, count)) {
vfree(page);
return -EFAULT;
}
/* Now do something with the data, here we just print it */
sscanf(page,”%d”,&my_data);
printk(“User has sent the value of %d\n”, my_data);

/* Free the allocated memory, don’t touch. */
vfree(page);
return count;
}
void hello_proc_exit(void)
{
/* Will block here and wait until kthread stops */
kthread_stop(t);
remove_proc_entry(ENTRY_NAME, NULL);
printk(“Removing /proc/%s.\n”, ENTRY_NAME);
}
module_init(hello_proc_init);
module_exit(hello_proc_exit);

__MACOSX/untitled folder 2/._penguin.c

untitled folder 2/Makefile.txt
ifneq ($(KERNELRELEASE),)
obj-m := hello_proc.o
else
KERNELDIR ?= \
/lib/modules/`uname -r`/build/
PWD := `pwd`
default:
$(MAKE) -C $(KERNELDIR) \
M=$(PWD) modules
endif
clean:
rm -f *.ko *.o Module* *mod*

__MACOSX/untitled folder 2/._Makefile.txt

untitled folder 2/Makefile-2.txt
ifneq ($(KERNELRELEASE),)
obj-m := penguin.o
else
KERNELDIR ?= \
/lib/modules/`uname -r`/build/
PWD := `pwd`
default:
$(MAKE) -C $(KERNELDIR) \
M=$(PWD) modules
endif
clean:
rm -f *.ko *.o Module* *mod*

__MACOSX/untitled folder 2/._Makefile-2.txt

untitled folder 2/hello_proc.c
#include #include #include #include #include MODULE_LICENSE(“GPL”); /* Kernel needs this license. */
#define ENTRY_NAME “helloworld”
#define PERMS 0644
#define PARENT NULL
/* Function declarations */
ssize_t procfile_read(struct file *filp, char __user *buf, size_t count,
loff_t *f_pos);
ssize_t procfile_write(struct file *filp, const char __user *buf, size_t count,
loff_t *f_pos);
/* Global variables go here */
/* This global structure is necessary to bind the regular file read and write
* operations to our special “read” and “write” functions instead. Don’t
* modify. (structs in C are like objects in other languages.)
*/
static struct file_operations hello_proc_ops = {
.owner = THIS_MODULE,
.read = procfile_read,
.write = procfile_write,
};

/* This function is called to create the special proc file entry on
* module load. This file is created as /proc/helloworld. */
int hello_proc_init(void) {
proc_create_data(ENTRY_NAME, 0, NULL, &hello_proc_ops, NULL);

/* This message will print in /var/log/syslog or on the first tty. */
printk(“/proc/%s created\n”, ENTRY_NAME);
return 0;
}
/* This function is called when someone tries to READ from the file
* /proc/helloworld. */
ssize_t procfile_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
/* Static variable? What does this do inside a C function? Take a look
* at the accepted answer in the link below:
* http://stackoverflow.com/questions/572547/what-does-static-mean-in-a-c-program
*/
static int finished = 0;
int ret;
char ret_buf[80];
/* Are we done reading? If so, we return 0 to indicate end-of-file */
if (finished) {
finished=0;
return 0;
}
finished = 1;
/* This message will print in /var/log/syslog or on the first tty. */
printk(“/proc/%s read called.\n”, ENTRY_NAME);

/* Take the string “Hello World!\n” and put it in ret_buf. Copy ret_buf
into the user-space buffer called buf. buf is what gets
* displayed to the user when they read the file. */
ret = sprintf(ret_buf, “Hello world!\n”);
if(copy_to_user(buf, ret_buf, ret)) {
ret = -EFAULT; //failed, let’s get out of here
}
/* Returning the number of characters returned to the reader. */
return ret;
}
/* This function is called when someone tries to WRITE to the file
* /proc/helloworld. */
ssize_t procfile_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{
char *page; /* don’t touch */

/* Allocating kernel memory, don’t touch. */
page = (char *) vmalloc(count);
if (!page)
return -ENOMEM;
/* Copy the data from the user space. Data is placed in page. */
if (copy_from_user(page, buf, count)) {
vfree(page);
return -EFAULT;
}
/* Now do something with the data, here we just print it */
printk(“User has sent the value of %s\n”, page);

/* Free the allocated memory, don’t touch. */
vfree(page);
/* Return the number of bytes written to the file. */
return count;
}
/* Called when module is unloaded. Function removes the proc file and
* prints a message to /var/log/syslog. */
void hello_proc_exit(void)
{
remove_proc_entry(ENTRY_NAME, NULL);
printk(“Removing /proc/%s.\n”, ENTRY_NAME);
}
/* Necessary module stuff. Says init function is hello_proc_init and
* exit function is hello_proc_exit. */
module_init(hello_proc_init);
module_exit(hello_proc_exit);

__MACOSX/untitled folder 2/._hello_proc.c

untitled folder 2/watch_penguin.sh
#!/bin/bash
watch -n 1 cat /proc/penguin

__MACOSX/untitled folder 2/._watch_penguin.sh

Project 3 Specification
Kernel Module Programming

Kernel Modules, Mutual Exclusion, and Scheduling

Final Submission Due: 3/27 at 11:59:59pm

Language Restrictions: C only

Purpose

This project introduces you to the nuts and bolts of kernel programming, concurrency, and
synchronization in the kernel. This project is divided into two parts and worth 40 points. This project
may be completed in partners or by yourself.

Part 1: remember Kernel Module

In Unix-like operating systems, the /proc interface is often used to set or read kernel information. For
example, take a look at /proc/cpuinfo and /proc/meminfo using the following commands:

$> cat /proc/cpuinfo

$> cat /proc/meminfo

Even though these proc files look like ordinary files, they are actually virtual kernel drivers! These
modules perform actions based on whether a user reads or writes to them.

You will write your own proc module called remember that

1. allows the user to write a string (max length 80)
2. allows the user to read back the string that was just added

For example:
$> echo “Hello there” > /proc/remember
$> cat /proc/remember
Hello there
$>

Please use the example proc module (hello_proc.c) and Makefile provided to you as a starting point.
Change the name of the module from helloworld to remember, create a global string of size 80 to hold
the string written, and use that global variable whenever a read is performed.

You can use the original 4.9 kernel or the 5.5.5 kernel.

Part 2: Your very own Virtual Printer

Congratulations, you are the proud owner of a new virtual printer called the penguin printer (a.k.a
“penguin”). Your task is to implement a printer scheduling algorithm. A printer is defined as a device
that accepts print jobs for documents into a queue and processes those documents. A maximum
number of jobs will be given. When a printer is loaded, it is initially running. Each job takes a specific

amount of time to process. Finally, the printer is stopped when the module is unloaded.

Your printer must keep track of the number and type of jobs in a queue. Jobs can come in at any time
and can be put on the queue instantaneously. A job must always be accepted if there is room. Jobs can
only be processed by the printer one at a time, and it takes the printer 1 second to look inside any spot
in the queue (whether it holds a job or not). Once a job is processed, the spot in the queue is cleared
and the printer can look for other jobs.

Task Specification

This is a classic exercise in modeling consumers and producers. The producer produces jobs and the
consumer is the printer. There are many pieces needed to provide a complete implementation discussed
below.

Step 1: Develop a penguin printer /proc module
Develop a /proc entry named /proc/penguin. In this project, you will be required to support a
printer job queue of size 10. You will accept the following 4 jobs:

• 1-page document (internally represented with a 1)
• 2-page document (internally represented with a 2)
• 3-page document (internally represented with a 3)
• 4-page document (internally represented with a 4)

As in a real printer, it takes varying time to process different types of jobs. Your printer must take 1
second to process a 1-page document, 2 seconds to process a 2-page document, 3 seconds to process a
3-page document, and 4 seconds to process a 4-page document. This processing time is in addition to
the 1 second it must take to look in any spot in the queue for an job.

Finally, the printer can break down. It also must accept the following job:

• maintenance (internally represented with a 5)

Maintenance takes a whopping 10 seconds, in addition to the 1 second it must take to look in any spot
in the queue for a job.

(Hint – you can “process” for a given amount of seconds by using the ssleep() function.)

You will place jobs on your queue by writing your jobs’s number to the /proc/penguin file. For
example, the following will put a 2-page document on the order queue:

$> echo 2 > /proc/penguin

If the queue is full, the printer code should return –ENOMEM and the job should not be placed on the
queue.

$> echo 2 > /proc/penguin
bash: echo: write error: Cannot allocate memory

Step 2: Reading from /proc/ penguin

In addition to accepting orders and commands, your printer must be able to display status information
by reading the device. Specifically, when someone reads from /proc/penguin, they should see:

• Current spot being looked at in the queue
• Current job being processed
• Total jobs processed

For example, take a look at this sample session:
$> insmod penguin.ko
$> cat /proc/penguin
Processing nothing at slot 2. Total jobs processed: 0.
$> echo 4 > /proc/penguin
$> cat /proc/penguin
Processing nothing at slot 8. Total jobs processed: 0.
$> cat /proc/penguin
PriProcessing 4-page document at slot 0. Total jobs processed: 0.
$> cat /proc/penguin
Processing 4-page document at slot 0. Total jobs processed: 0.
$> cat /proc/penguin
Processing nothing at slot 2. Total jobs processed: 1.
$> rmmod penguin

The insmod and rmmod commands load and unload the kernel module, respectively. After starting the
printer, I placed 4-page document on the queue. However, when immediately reading from
/proc/penguin, my printer was not yet looking in the spot in the queue with the 4-page document.
Finally, it looks in the right spot and “processes” the 4-page for 4 seconds, so I was able to read from
/proc/penguin twice and get the same processing status.

Step 3: Use a kthread

You must use a kthread to allow the printer to run in the background and process orders. Please look at
my example, which starts a kthread on module load.

Step 4: Mutual Exclusion

You may have been getting lucky up until now, but what happens if the printer kthread is modifying a
spot in your job queue that you are trying to read at the same time? What happens if you are trying to
add a job to the queue at the same time that the printer is taking one away? If you have any global
variables in your code that can be accessed by more than one thread at a time, you must protect the
reading and writing of those variables with mutexes (semaphores with only 0 and 1 values). If not,
your entire driver could randomly crash. The probability of this goes up with the more cores you have
in your virtual machine. Use kernel mutexes to protect critical sections of code where you read or
write to global variables.

Extra Credit

The top five submissions as measured by the above evaluation procedure will receive +5 points to their
project 3 grade. The metric to optimize is: total jobs processed.

Full Project Submission Procedure

You will need to submit the following files:

• remember.c (not the .ko or the Makefile)
• penguin.c (not the .ko or the Makefile)
• The filled-in Project3-README x. (If you are a Mac user, please keep the format as Word or

else convert to a pdf. I have problems grading Pages documents on a non-Mac.)

Project 3 Specification
Kernel Module Programming

Kernel Modules, Mutual Exclusion, and Scheduling

Final Submission Due: 3/27 at 11:59:59pm

Language Restrictions: C only

Purpose

This project introduces you to the nuts and bolts of kernel programming, concurrency, and
synchronization in the kernel. This project is divided into two parts and worth 40 points. This project
may be completed in partners or by yourself.

Part 1: remember Kernel Module

In Unix-like operating systems, the /proc interface is often used to set or read kernel information. For
example, take a look at /proc/cpuinfo and /proc/meminfo using the following commands:

$> cat /proc/cpuinfo

$> cat /proc/meminfo

Even though these proc files look like ordinary files, they are actually virtual kernel drivers! These
modules perform actions based on whether a user reads or writes to them.

You will write your own proc module called remember that

1. allows the user to write a string (max length 80)
2. allows the user to read back the string that was just added

For example:
$> echo “Hello there” > /proc/remember
$> cat /proc/remember
Hello there
$>

Please use the example proc module (hello_proc.c) and Makefile provided to you as a starting point.
Change the name of the module from helloworld to remember, create a global string of size 80 to hold
the string written, and use that global variable whenever a read is performed.

You can use the original 4.9 kernel or the 5.5.5 kernel.

Part 2: Your very own Virtual Printer

Congratulations, you are the proud owner of a new virtual printer called the penguin printer (a.k.a
“penguin”). Your task is to implement a printer scheduling algorithm. A printer is defined as a device
that accepts print jobs for documents into a queue and processes those documents. A maximum
number of jobs will be given. When a printer is loaded, it is initially running. Each job takes a specific

amount of time to process. Finally, the printer is stopped when the module is unloaded.

Your printer must keep track of the number and type of jobs in a queue. Jobs can come in at any time
and can be put on the queue instantaneously. A job must always be accepted if there is room. Jobs can
only be processed by the printer one at a time, and it takes the printer 1 second to look inside any spot
in the queue (whether it holds a job or not). Once a job is processed, the spot in the queue is cleared
and the printer can look for other jobs.

Task Specification

This is a classic exercise in modeling consumers and producers. The producer produces jobs and the
consumer is the printer. There are many pieces needed to provide a complete implementation discussed
below.

Step 1: Develop a penguin printer /proc module
Develop a /proc entry named /proc/penguin. In this project, you will be required to support a
printer job queue of size 10. You will accept the following 4 jobs:

• 1-page document (internally represented with a 1)
• 2-page document (internally represented with a 2)
• 3-page document (internally represented with a 3)
• 4-page document (internally represented with a 4)

As in a real printer, it takes varying time to process different types of jobs. Your printer must take 1
second to process a 1-page document, 2 seconds to process a 2-page document, 3 seconds to process a
3-page document, and 4 seconds to process a 4-page document. This processing time is in addition to
the 1 second it must take to look in any spot in the queue for an job.

Finally, the printer can break down. It also must accept the following job:

• maintenance (internally represented with a 5)

Maintenance takes a whopping 10 seconds, in addition to the 1 second it must take to look in any spot
in the queue for a job.

(Hint – you can “process” for a given amount of seconds by using the ssleep() function.)

You will place jobs on your queue by writing your jobs’s number to the /proc/penguin file. For
example, the following will put a 2-page document on the order queue:

$> echo 2 > /proc/penguin

If the queue is full, the printer code should return –ENOMEM and the job should not be placed on the
queue.

$> echo 2 > /proc/penguin
bash: echo: write error: Cannot allocate memory

Step 2: Reading from /proc/ penguin

In addition to accepting orders and commands, your printer must be able to display status information
by reading the device. Specifically, when someone reads from /proc/penguin, they should see:

• Current spot being looked at in the queue
• Current job being processed
• Total jobs processed

For example, take a look at this sample session:
$> insmod penguin.ko
$> cat /proc/penguin
Processing nothing at slot 2. Total jobs processed: 0.
$> echo 4 > /proc/penguin
$> cat /proc/penguin
Processing nothing at slot 8. Total jobs processed: 0.
$> cat /proc/penguin
PriProcessing 4-page document at slot 0. Total jobs processed: 0.
$> cat /proc/penguin
Processing 4-page document at slot 0. Total jobs processed: 0.
$> cat /proc/penguin
Processing nothing at slot 2. Total jobs processed: 1.
$> rmmod penguin

The insmod and rmmod commands load and unload the kernel module, respectively. After starting the
printer, I placed 4-page document on the queue. However, when immediately reading from
/proc/penguin, my printer was not yet looking in the spot in the queue with the 4-page document.
Finally, it looks in the right spot and “processes” the 4-page for 4 seconds, so I was able to read from
/proc/penguin twice and get the same processing status.

Step 3: Use a kthread

You must use a kthread to allow the printer to run in the background and process orders. Please look at
my example, which starts a kthread on module load.

Step 4: Mutual Exclusion

You may have been getting lucky up until now, but what happens if the printer kthread is modifying a
spot in your job queue that you are trying to read at the same time? What happens if you are trying to
add a job to the queue at the same time that the printer is taking one away? If you have any global
variables in your code that can be accessed by more than one thread at a time, you must protect the
reading and writing of those variables with mutexes (semaphores with only 0 and 1 values). If not,
your entire driver could randomly crash. The probability of this goes up with the more cores you have
in your virtual machine. Use kernel mutexes to protect critical sections of code where you read or
write to global variables.

Extra Credit

The top five submissions as measured by the above evaluation procedure will receive +5 points to their
project 3 grade. The metric to optimize is: total jobs processed.

Full Project Submission Procedure

You will need to submit the following files:

• remember.c (not the .ko or the Makefile)
• penguin.c (not the .ko or the Makefile)
• The filled-in Project3-README x. (If you are a Mac user, please keep the format as Word or

else convert to a pdf. I have problems grading Pages documents on a non-Mac.)

Calculate your order
Pages (275 words)
Standard price: $0.00
Client Reviews
4.9
Sitejabber
4.6
Trustpilot
4.8
Our Guarantees
100% Confidentiality
Information about customers is confidential and never disclosed to third parties.
Original Writing
We complete all papers from scratch. You can get a plagiarism report.
Timely Delivery
No missed deadlines – 97% of assignments are completed in time.
Money Back
If you're confident that a writer didn't follow your order details, ask for a refund.

Calculate the price of your order

You will get a personal manager and a discount.
We'll send you the first draft for approval by at
Total price:
$0.00
Power up Your Academic Success with the
Team of Professionals. We’ve Got Your Back.
Power up Your Study Success with Experts We’ve Got Your Back.

Order your essay today and save 30% with the discount code ESSAYHELP