Skip to content

Commit 3aacc0a

Browse files
committed
Initialize project
0 parents  commit 3aacc0a

28 files changed

+2445
-0
lines changed

Makefile

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#
2+
# Students' Makefile for the Malloc Lab
3+
#
4+
TEAM = bovik
5+
VERSION = 1
6+
HANDINDIR = /afs/cs.cmu.edu/academic/class/15213-f01/malloclab/handin
7+
8+
CC = gcc
9+
CFLAGS = -Wall -O2 -m32
10+
11+
OBJS = mdriver.o mm.o memlib.o fsecs.o fcyc.o clock.o ftimer.o
12+
13+
mdriver: $(OBJS)
14+
$(CC) $(CFLAGS) -o mdriver $(OBJS)
15+
16+
mdriver.o: mdriver.c fsecs.h fcyc.h clock.h memlib.h config.h mm.h
17+
memlib.o: memlib.c memlib.h
18+
mm.o: mm.c mm.h memlib.h
19+
fsecs.o: fsecs.c fsecs.h config.h
20+
fcyc.o: fcyc.c fcyc.h
21+
ftimer.o: ftimer.c ftimer.h config.h
22+
clock.o: clock.c clock.h
23+
24+
handin:
25+
cp mm.c $(HANDINDIR)/$(TEAM)-$(VERSION)-mm.c
26+
27+
clean:
28+
rm -f *~ *.o mdriver
29+
30+

Malloc_tutorial.pdf

204 KB
Binary file not shown.

README

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#####################################################################
2+
# CS:APP Malloc Lab
3+
# Handout files for students
4+
#
5+
# Copyright (c) 2002, R. Bryant and D. O'Hallaron, All rights reserved.
6+
# May not be used, modified, or copied without permission.
7+
#
8+
######################################################################
9+
10+
***********
11+
Main Files:
12+
***********
13+
14+
mm.{c,h}
15+
Your solution malloc package. mm.c is the file that you
16+
will be handing in, and is the only file you should modify.
17+
18+
mdriver.c
19+
The malloc driver that tests your mm.c file
20+
21+
short{1,2}-bal.rep
22+
Two tiny tracefiles to help you get started.
23+
24+
Makefile
25+
Builds the driver
26+
27+
**********************************
28+
Other support files for the driver
29+
**********************************
30+
31+
config.h Configures the malloc lab driver
32+
fsecs.{c,h} Wrapper function for the different timer packages
33+
clock.{c,h} Routines for accessing the Pentium and Alpha cycle counters
34+
fcyc.{c,h} Timer functions based on cycle counters
35+
ftimer.{c,h} Timer functions based on interval timers and gettimeofday()
36+
memlib.{c,h} Models the heap and sbrk function
37+
38+
*******************************
39+
Building and running the driver
40+
*******************************
41+
To build the driver, type "make" to the shell.
42+
43+
To run the driver on a tiny test trace:
44+
45+
unix> mdriver -V -f short1-bal.rep
46+
47+
The -V option prints out helpful tracing and summary information.
48+
49+
To get a list of the driver flags:
50+
51+
unix> mdriver -h
52+

clock.c

Lines changed: 279 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,279 @@
1+
/*
2+
* clock.c - Routines for using the cycle counters on x86,
3+
* Alpha, and Sparc boxes.
4+
*
5+
* Copyright (c) 2002, R. Bryant and D. O'Hallaron, All rights reserved.
6+
* May not be used, modified, or copied without permission.
7+
*/
8+
9+
#include <stdio.h>
10+
#include <stdlib.h>
11+
#include <unistd.h>
12+
#include <sys/times.h>
13+
#include "clock.h"
14+
15+
16+
/*******************************************************
17+
* Machine dependent functions
18+
*
19+
* Note: the constants __i386__ and __alpha
20+
* are set by GCC when it calls the C preprocessor
21+
* You can verify this for yourself using gcc -v.
22+
*******************************************************/
23+
24+
#if defined(__i386__)
25+
/*******************************************************
26+
* Pentium versions of start_counter() and get_counter()
27+
*******************************************************/
28+
29+
30+
/* $begin x86cyclecounter */
31+
/* Initialize the cycle counter */
32+
static unsigned cyc_hi = 0;
33+
static unsigned cyc_lo = 0;
34+
35+
36+
/* Set *hi and *lo to the high and low order bits of the cycle counter.
37+
Implementation requires assembly code to use the rdtsc instruction. */
38+
void access_counter(unsigned *hi, unsigned *lo)
39+
{
40+
asm("rdtsc; movl %%edx,%0; movl %%eax,%1" /* Read cycle counter */
41+
: "=r" (*hi), "=r" (*lo) /* and move results to */
42+
: /* No input */ /* the two outputs */
43+
: "%edx", "%eax");
44+
}
45+
46+
/* Record the current value of the cycle counter. */
47+
void start_counter()
48+
{
49+
access_counter(&cyc_hi, &cyc_lo);
50+
}
51+
52+
/* Return the number of cycles since the last call to start_counter. */
53+
double get_counter()
54+
{
55+
unsigned ncyc_hi, ncyc_lo;
56+
unsigned hi, lo, borrow;
57+
double result;
58+
59+
/* Get cycle counter */
60+
access_counter(&ncyc_hi, &ncyc_lo);
61+
62+
/* Do double precision subtraction */
63+
lo = ncyc_lo - cyc_lo;
64+
borrow = lo > ncyc_lo;
65+
hi = ncyc_hi - cyc_hi - borrow;
66+
result = (double) hi * (1 << 30) * 4 + lo;
67+
if (result < 0) {
68+
fprintf(stderr, "Error: counter returns neg value: %.0f\n", result);
69+
}
70+
return result;
71+
}
72+
/* $end x86cyclecounter */
73+
74+
#elif defined(__alpha)
75+
76+
/****************************************************
77+
* Alpha versions of start_counter() and get_counter()
78+
***************************************************/
79+
80+
/* Initialize the cycle counter */
81+
static unsigned cyc_hi = 0;
82+
static unsigned cyc_lo = 0;
83+
84+
85+
/* Use Alpha cycle timer to compute cycles. Then use
86+
measured clock speed to compute seconds
87+
*/
88+
89+
/*
90+
* counterRoutine is an array of Alpha instructions to access
91+
* the Alpha's processor cycle counter. It uses the rpcc
92+
* instruction to access the counter. This 64 bit register is
93+
* divided into two parts. The lower 32 bits are the cycles
94+
* used by the current process. The upper 32 bits are wall
95+
* clock cycles. These instructions read the counter, and
96+
* convert the lower 32 bits into an unsigned int - this is the
97+
* user space counter value.
98+
* NOTE: The counter has a very limited time span. With a
99+
* 450MhZ clock the counter can time things for about 9
100+
* seconds. */
101+
static unsigned int counterRoutine[] =
102+
{
103+
0x601fc000u,
104+
0x401f0000u,
105+
0x6bfa8001u
106+
};
107+
108+
/* Cast the above instructions into a function. */
109+
static unsigned int (*counter)(void)= (void *)counterRoutine;
110+
111+
112+
void start_counter()
113+
{
114+
/* Get cycle counter */
115+
cyc_hi = 0;
116+
cyc_lo = counter();
117+
}
118+
119+
double get_counter()
120+
{
121+
unsigned ncyc_hi, ncyc_lo;
122+
unsigned hi, lo, borrow;
123+
double result;
124+
ncyc_lo = counter();
125+
ncyc_hi = 0;
126+
lo = ncyc_lo - cyc_lo;
127+
borrow = lo > ncyc_lo;
128+
hi = ncyc_hi - cyc_hi - borrow;
129+
result = (double) hi * (1 << 30) * 4 + lo;
130+
if (result < 0) {
131+
fprintf(stderr, "Error: Cycle counter returning negative value: %.0f\n", result);
132+
}
133+
return result;
134+
}
135+
136+
#else
137+
138+
/****************************************************************
139+
* All the other platforms for which we haven't implemented cycle
140+
* counter routines. Newer models of sparcs (v8plus) have cycle
141+
* counters that can be accessed from user programs, but since there
142+
* are still many sparc boxes out there that don't support this, we
143+
* haven't provided a Sparc version here.
144+
***************************************************************/
145+
146+
void start_counter()
147+
{
148+
printf("ERROR: You are trying to use a start_counter routine in clock.c\n");
149+
printf("that has not been implemented yet on this platform.\n");
150+
printf("Please choose another timing package in config.h.\n");
151+
exit(1);
152+
}
153+
154+
double get_counter()
155+
{
156+
printf("ERROR: You are trying to use a get_counter routine in clock.c\n");
157+
printf("that has not been implemented yet on this platform.\n");
158+
printf("Please choose another timing package in config.h.\n");
159+
exit(1);
160+
}
161+
#endif
162+
163+
164+
165+
166+
/*******************************
167+
* Machine-independent functions
168+
******************************/
169+
double ovhd()
170+
{
171+
/* Do it twice to eliminate cache effects */
172+
int i;
173+
double result;
174+
175+
for (i = 0; i < 2; i++) {
176+
start_counter();
177+
result = get_counter();
178+
}
179+
return result;
180+
}
181+
182+
/* $begin mhz */
183+
/* Estimate the clock rate by measuring the cycles that elapse */
184+
/* while sleeping for sleeptime seconds */
185+
double mhz_full(int verbose, int sleeptime)
186+
{
187+
double rate;
188+
189+
start_counter();
190+
sleep(sleeptime);
191+
rate = get_counter() / (1e6*sleeptime);
192+
if (verbose)
193+
printf("Processor clock rate ~= %.1f MHz\n", rate);
194+
return rate;
195+
}
196+
/* $end mhz */
197+
198+
/* Version using a default sleeptime */
199+
double mhz(int verbose)
200+
{
201+
return mhz_full(verbose, 2);
202+
}
203+
204+
/** Special counters that compensate for timer interrupt overhead */
205+
206+
static double cyc_per_tick = 0.0;
207+
208+
#define NEVENT 100
209+
#define THRESHOLD 1000
210+
#define RECORDTHRESH 3000
211+
212+
/* Attempt to see how much time is used by timer interrupt */
213+
static void callibrate(int verbose)
214+
{
215+
double oldt;
216+
struct tms t;
217+
clock_t oldc;
218+
int e = 0;
219+
220+
times(&t);
221+
oldc = t.tms_utime;
222+
start_counter();
223+
oldt = get_counter();
224+
while (e <NEVENT) {
225+
double newt = get_counter();
226+
227+
if (newt-oldt >= THRESHOLD) {
228+
clock_t newc;
229+
times(&t);
230+
newc = t.tms_utime;
231+
if (newc > oldc) {
232+
double cpt = (newt-oldt)/(newc-oldc);
233+
if ((cyc_per_tick == 0.0 || cyc_per_tick > cpt) && cpt > RECORDTHRESH)
234+
cyc_per_tick = cpt;
235+
/*
236+
if (verbose)
237+
printf("Saw event lasting %.0f cycles and %d ticks. Ratio = %f\n",
238+
newt-oldt, (int) (newc-oldc), cpt);
239+
*/
240+
e++;
241+
oldc = newc;
242+
}
243+
oldt = newt;
244+
}
245+
}
246+
if (verbose)
247+
printf("Setting cyc_per_tick to %f\n", cyc_per_tick);
248+
}
249+
250+
static clock_t start_tick = 0;
251+
252+
void start_comp_counter()
253+
{
254+
struct tms t;
255+
256+
if (cyc_per_tick == 0.0)
257+
callibrate(0);
258+
times(&t);
259+
start_tick = t.tms_utime;
260+
start_counter();
261+
}
262+
263+
double get_comp_counter()
264+
{
265+
double time = get_counter();
266+
double ctime;
267+
struct tms t;
268+
clock_t ticks;
269+
270+
times(&t);
271+
ticks = t.tms_utime - start_tick;
272+
ctime = time - ticks*cyc_per_tick;
273+
/*
274+
printf("Measured %.0f cycles. Ticks = %d. Corrected %.0f cycles\n",
275+
time, (int) ticks, ctime);
276+
*/
277+
return ctime;
278+
}
279+

clock.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/* Routines for using cycle counter */
2+
3+
/* Start the counter */
4+
void start_counter();
5+
6+
/* Get # cycles since counter started */
7+
double get_counter();
8+
9+
/* Measure overhead for counter */
10+
double ovhd();
11+
12+
/* Determine clock rate of processor (using a default sleeptime) */
13+
double mhz(int verbose);
14+
15+
/* Determine clock rate of processor, having more control over accuracy */
16+
double mhz_full(int verbose, int sleeptime);
17+
18+
/** Special counters that compensate for timer interrupt overhead */
19+
20+
void start_comp_counter();
21+
22+
double get_comp_counter();

clock.o

2.43 KB
Binary file not shown.

0 commit comments

Comments
 (0)