Supplementary for Project 1

Download Report

Transcript Supplementary for Project 1

Project 1
Project 1
Supplemental Lecture
Joe Mongeluzzi
Jason Zhao
Cornell CS 4411, September 14, 2012
Project 1
Today’s Lecture




Administrative Information
C Pointer Hints
Project 1 FAQ
Q&A/Discussion
Project 1
Administrative Information
 Project 1 due Sept. 21, 11:59 PM
 Submission via CMS
 Submit single zip file
 don’t create an extra folder to hold the content
 submit only source files, in addition to README
 don’t encrypt!
 Instructions will be posted on website
 Correctness and elegance are prized
 Comment code, use proper indentation, remove
excess debug (printf) statements
Project 1
Pointer casting
 A pointer has two components:
 starting address of the data being pointed to
 size of data type associated with this memory location
int a = 66051;
int *x = &a;
x = 0x00001004
*x = 0x00010203
pointer x: data starts from 0x00001004 and spans 4 bytes
0x00001000
0
0
0
0
3
2
1
0x00001004
endianness?
0
0
0
0
0
0
0
0
0
Project 1
Pointer casting
 Casting the pointer changes only the way the

memory is interpreted.
It does not change the memory contents or the
address stored in the pointer.
int
int
a = 66051;
*x = &a;
x
*x
y
*y
char *y;
y = (char*) x;
0
0
0x00001004
0x00010203
0x00001004
0x03
pointer y: data starts from 0x00001004 and spans 1 byte
pointer x: data starts from 0x00001004 and spans 4 bytes
0x00001000
0
=
=
=
=
0
3
0
2
0
0
1
0x00001004
0
0
0
0
0
0
0
0
0
Project 1
Pointer casting
 We can change the values from the casted

pointer if we like.
No array bounds check in C!
int
a = 66501;
int *x = &a;
char *y = (char*) x;
x
*x
y
*y
y[2]
=
=
=
=
=
0
0
0x00001004
0x00010203
0x00001004
0x04
0x01
0x00001000
0
0
0
0
3
0
0
2
0
1
0x00001004
0
0
0
0
0
0
0
Project 1
Structures
struct base {
int first;
int second;
};
struct derived {
struct base original;
int third;
};
struct base* b;
struct derived* d;
pointer b: data starts from 0x00001000 and spans 8 bytes (struct is aligned)
0x00001000
0
0
first
0
0
0
0
0
second
0
0
0
0
0
0
0
0
0
Project 1
Structures
struct base {
int first;
int second;
};
struct derived {
struct base original;
int third;
};
struct base* b;
struct derived* d;
pointer d: data starts from 0x00001000 and spans 12 bytes (struct is aligned)
0x00001000
0
0
0
0
0
original
0
0
0
0
0
0
third
0
0
0
0
0
Project 1
Common questions on casting
 Casting from a derived struct pointer to the base
struct pointer is safe
 any operation that works on data members of the
base struct will not write outside of the space
allocated for the derived struct
struct base *b = (struct base*) d;
b->first = 0xdaed; b->second = 0xfeeb;
pointer d: data starts from 0x00001000 and spans 12 bytes (struct is aligned)
dc
ea
af
d
e
b
ea
b
e
ef
0
0
0
0
pointer b: data starts from 0x00001000 and spans 8 bytes.
Project 1
Common questions on casting
 What about casting from base struct to derived
struct?
 unless you are very sure you will not touch data fields

other than those in the base struct
but if that is the case, why did you perform the cast?
struct derived *some_d = (struct derived*) some_b;
some_d->first = 1;
some_d->second = 2;
some_d->third = 3;
Project 1
Common questions on casting
 Writing outside of known bounds may cause
unpredictable behavior
 may overwrite another variable
 may overwrite stack (and thus modify return address;
a common exploit)
 usually just crashes
struct derived *some_d = (struct derived*) some_b;
some_d->first = 1;
some_d->second = 2;
some_d->third = 3;
Project 1
void* pointers
 Review: a pointer has two components
 starting address of the data being pointed to
 size of data type associated with this memory location
 void* pointers are not associated with any data
type
 has only a starting address
 no known size, therefore not possible to tell where

data ends in memory
malloc() is a good example
Project 1
Casting void* pointers
 casting to void* from other pointer types
 automatic, no need to prepend (void*)
 other pointers can easily cast to void*; just ignore the
size of the data type
 casting to other pointer types from void*
 explicit cast required
 destination data type supplies the size of the data
type
Project 1
Queue
 All* queue operations take in an existing queue.
 int queue_append(queue_t, void *item);
 Append takes a pointer to an existing object, it is your job
to link that pointer/object to the rest of your queue
 int queue_deque(queue_t queue, void **item);
 Dequeue removes the first item from the queue and
returns it to the caller via the variable “item”
 int queue_delete(queue_t queue, void **item);
 Delete takes a pointer to the exact element that you
appended and removes it from the queue
*all queue functions except queue_new()
Project 1
Queue Abstraction
Head
Ptr1
Ptr2
Ptr3
Ptr4
Obj1
Obj2
Obj3
Obj4
myPtr
Queue_dequeue(myQ, myPtr)
dPtr
Queue_delete(myQ, dPtr)
Project 1
Queue
 int queue_iterate(queue_t, PFAny, void *);
 Iterate applies a functions f to all elements of the
queue. Corner cases, if any application of the function
f fails (i.e., returns a -1), immediately terminate the
iteration and return -1.
 int queue_free(queue_t);
 Free returns all memory allocated to the queue
structure back to the OS. Free does not free the
memory of the actual objects stored in the queue.
Project 1
Queue
 General *Pointers:
 Return correct error codes in all cases – unlike Java,

C does not have exceptions therefore you must
ensure your queue returns the correct error code
when something goes wrong.
Check your code for memory leaks – Visual Studio
provides tools for detecting memory leaks but you
should still reason about your code!
Project 1
Minithread
 Minithreads are the fundamental building block of
your OS
 You must implement the entire infrastructure to
support minithreads including but not limited to:





Thread creation
Thread state (TCB)
Context switching
Thread blocking
Thread cleanup/deletion
 As an OS, you must NEVER terminate. This is
achieved using an idle thread.
 What should the idle thread do?
Project 1
Typical PortOS Execution
Thread
Creation
System Initialize
Thread
Execution
Ready
Idle Thread
Waiting
Thread
Deletion
Thread
Termination
Running
Project 1
Semaphore
 Low level synchronization primitive
 What is the purpose of a semaphore?
 Mutual exclusion
 Eliminates busy waiting
 Common operations
 semaphore_P – “procures” the semaphore

 P is a potentially blocking operation
semaphore_V – “vacates” the semaphore
 V should never block
Project 1
Semaphore Internals
 What should a semaphore store?
 Count
 List of threads
 TAS lock
 Has internal state! However the internal state of
a semaphore should NEVER be made visible to
observers.
 Uses TAS locks, however you should omit the
locking in project 1.
 Be sure to initialize the semaphore before you
use it.
Project 1
Application
 Last part of the project is a simple application



that demonstrates your system components
Free to make this from scratch, but must follow
description in assignment
Should use semaphores, no busy spinning!
Test with different values for N (employees) and
M (customers)
Project 1
Questions
Questions?