Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
S
Systems744
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
SHREYANSH JAIN
Systems744
Commits
01b4e45a
Commit
01b4e45a
authored
Aug 29, 2019
by
desiredeveloper
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
adding assignment 2
parent
2f69b239
Changes
21
Show whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
2245 additions
and
0 deletions
+2245
-0
assignment2/sync-problems/metro
assignment2/sync-problems/metro
+0
-0
assignment2/sync-problems/reaction
assignment2/sync-problems/reaction
+0
-0
assignment3/Assignment 3.pdf
assignment3/Assignment 3.pdf
+0
-0
assignment3/malloclab-handout/Makefile
assignment3/malloclab-handout/Makefile
+26
-0
assignment3/malloclab-handout/README
assignment3/malloclab-handout/README
+52
-0
assignment3/malloclab-handout/clock.c
assignment3/malloclab-handout/clock.c
+279
-0
assignment3/malloclab-handout/clock.h
assignment3/malloclab-handout/clock.h
+22
-0
assignment3/malloclab-handout/config.h
assignment3/malloclab-handout/config.h
+72
-0
assignment3/malloclab-handout/fcyc.c
assignment3/malloclab-handout/fcyc.c
+251
-0
assignment3/malloclab-handout/fcyc.h
assignment3/malloclab-handout/fcyc.h
+68
-0
assignment3/malloclab-handout/fsecs.c
assignment3/malloclab-handout/fsecs.c
+57
-0
assignment3/malloclab-handout/fsecs.h
assignment3/malloclab-handout/fsecs.h
+4
-0
assignment3/malloclab-handout/ftimer.c
assignment3/malloclab-handout/ftimer.c
+106
-0
assignment3/malloclab-handout/ftimer.h
assignment3/malloclab-handout/ftimer.h
+14
-0
assignment3/malloclab-handout/mdriver.c
assignment3/malloclab-handout/mdriver.c
+1017
-0
assignment3/malloclab-handout/memlib.c
assignment3/malloclab-handout/memlib.c
+101
-0
assignment3/malloclab-handout/memlib.h
assignment3/malloclab-handout/memlib.h
+11
-0
assignment3/malloclab-handout/mm.c
assignment3/malloclab-handout/mm.c
+110
-0
assignment3/malloclab-handout/mm.h
assignment3/malloclab-handout/mm.h
+23
-0
assignment3/malloclab-handout/short1-bal.rep
assignment3/malloclab-handout/short1-bal.rep
+16
-0
assignment3/malloclab-handout/short2-bal.rep
assignment3/malloclab-handout/short2-bal.rep
+16
-0
No files found.
assignment2/sync-problems/metro
0 → 100755
View file @
01b4e45a
File added
assignment2/sync-problems/reaction
0 → 100755
View file @
01b4e45a
File added
assignment3/Assignment 3.pdf
0 → 100644
View file @
01b4e45a
File added
assignment3/malloclab-handout/Makefile
0 → 100644
View file @
01b4e45a
#
# Students' Makefile for the Malloc Lab
#
TEAM
=
TIGERS
VERSION
=
1
CC
=
gcc
CFLAGS
=
-Wall
-O2
-m32
OBJS
=
mdriver.o mm.o memlib.o fsecs.o fcyc.o clock.o ftimer.o
mdriver
:
$(OBJS)
$(CC)
$(CFLAGS)
-o
mdriver
$(OBJS)
mdriver.o
:
mdriver.c fsecs.h fcyc.h clock.h memlib.h config.h mm.h
memlib.o
:
memlib.c memlib.h
mm.o
:
mm.c mm.h memlib.h
fsecs.o
:
fsecs.c fsecs.h config.h
fcyc.o
:
fcyc.c fcyc.h
ftimer.o
:
ftimer.c ftimer.h config.h
clock.o
:
clock.c clock.h
clean
:
rm
-f
*
~
*
.o mdriver
assignment3/malloclab-handout/README
0 → 100644
View file @
01b4e45a
#####################################################################
# CS:APP Malloc Lab
# Handout files for students
#
# Copyright (c) 2002, R. Bryant and D. O'Hallaron, All rights reserved.
# May not be used, modified, or copied without permission.
#
######################################################################
***********
Main Files:
***********
mm.{c,h}
Your solution malloc package. mm.c is the file that you
will be handing in, and is the only file you should modify.
mdriver.c
The malloc driver that tests your mm.c file
short{1,2}-bal.rep
Two tiny tracefiles to help you get started.
Makefile
Builds the driver
**********************************
Other support files for the driver
**********************************
config.h Configures the malloc lab driver
fsecs.{c,h} Wrapper function for the different timer packages
clock.{c,h} Routines for accessing the Pentium and Alpha cycle counters
fcyc.{c,h} Timer functions based on cycle counters
ftimer.{c,h} Timer functions based on interval timers and gettimeofday()
memlib.{c,h} Models the heap and sbrk function
*******************************
Building and running the driver
*******************************
To build the driver, type "make" to the shell.
To run the driver on a tiny test trace:
shell> ./mdriver -V -f short1-bal.rep
The -V option prints out helpful tracing and summary information.
To get a list of the driver flags:
shell> ./mdriver -h
assignment3/malloclab-handout/clock.c
0 → 100644
View file @
01b4e45a
/*
* clock.c - Routines for using the cycle counters on x86,
* Alpha, and Sparc boxes.
*
* Copyright (c) 2002, R. Bryant and D. O'Hallaron, All rights reserved.
* May not be used, modified, or copied without permission.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/times.h>
#include "clock.h"
/*******************************************************
* Machine dependent functions
*
* Note: the constants __i386__ and __alpha
* are set by GCC when it calls the C preprocessor
* You can verify this for yourself using gcc -v.
*******************************************************/
#if defined(__i386__)
/*******************************************************
* Pentium versions of start_counter() and get_counter()
*******************************************************/
/* $begin x86cyclecounter */
/* Initialize the cycle counter */
static
unsigned
cyc_hi
=
0
;
static
unsigned
cyc_lo
=
0
;
/* Set *hi and *lo to the high and low order bits of the cycle counter.
Implementation requires assembly code to use the rdtsc instruction. */
void
access_counter
(
unsigned
*
hi
,
unsigned
*
lo
)
{
asm
(
"rdtsc; movl %%edx,%0; movl %%eax,%1"
/* Read cycle counter */
:
"=r"
(
*
hi
),
"=r"
(
*
lo
)
/* and move results to */
:
/* No input */
/* the two outputs */
:
"%edx"
,
"%eax"
);
}
/* Record the current value of the cycle counter. */
void
start_counter
()
{
access_counter
(
&
cyc_hi
,
&
cyc_lo
);
}
/* Return the number of cycles since the last call to start_counter. */
double
get_counter
()
{
unsigned
ncyc_hi
,
ncyc_lo
;
unsigned
hi
,
lo
,
borrow
;
double
result
;
/* Get cycle counter */
access_counter
(
&
ncyc_hi
,
&
ncyc_lo
);
/* Do double precision subtraction */
lo
=
ncyc_lo
-
cyc_lo
;
borrow
=
lo
>
ncyc_lo
;
hi
=
ncyc_hi
-
cyc_hi
-
borrow
;
result
=
(
double
)
hi
*
(
1
<<
30
)
*
4
+
lo
;
if
(
result
<
0
)
{
fprintf
(
stderr
,
"Error: counter returns neg value: %.0f
\n
"
,
result
);
}
return
result
;
}
/* $end x86cyclecounter */
#elif defined(__alpha)
/****************************************************
* Alpha versions of start_counter() and get_counter()
***************************************************/
/* Initialize the cycle counter */
static
unsigned
cyc_hi
=
0
;
static
unsigned
cyc_lo
=
0
;
/* Use Alpha cycle timer to compute cycles. Then use
measured clock speed to compute seconds
*/
/*
* counterRoutine is an array of Alpha instructions to access
* the Alpha's processor cycle counter. It uses the rpcc
* instruction to access the counter. This 64 bit register is
* divided into two parts. The lower 32 bits are the cycles
* used by the current process. The upper 32 bits are wall
* clock cycles. These instructions read the counter, and
* convert the lower 32 bits into an unsigned int - this is the
* user space counter value.
* NOTE: The counter has a very limited time span. With a
* 450MhZ clock the counter can time things for about 9
* seconds. */
static
unsigned
int
counterRoutine
[]
=
{
0x601fc000u
,
0x401f0000u
,
0x6bfa8001u
};
/* Cast the above instructions into a function. */
static
unsigned
int
(
*
counter
)(
void
)
=
(
void
*
)
counterRoutine
;
void
start_counter
()
{
/* Get cycle counter */
cyc_hi
=
0
;
cyc_lo
=
counter
();
}
double
get_counter
()
{
unsigned
ncyc_hi
,
ncyc_lo
;
unsigned
hi
,
lo
,
borrow
;
double
result
;
ncyc_lo
=
counter
();
ncyc_hi
=
0
;
lo
=
ncyc_lo
-
cyc_lo
;
borrow
=
lo
>
ncyc_lo
;
hi
=
ncyc_hi
-
cyc_hi
-
borrow
;
result
=
(
double
)
hi
*
(
1
<<
30
)
*
4
+
lo
;
if
(
result
<
0
)
{
fprintf
(
stderr
,
"Error: Cycle counter returning negative value: %.0f
\n
"
,
result
);
}
return
result
;
}
#else
/****************************************************************
* All the other platforms for which we haven't implemented cycle
* counter routines. Newer models of sparcs (v8plus) have cycle
* counters that can be accessed from user programs, but since there
* are still many sparc boxes out there that don't support this, we
* haven't provided a Sparc version here.
***************************************************************/
void
start_counter
()
{
printf
(
"ERROR: You are trying to use a start_counter routine in clock.c
\n
"
);
printf
(
"that has not been implemented yet on this platform.
\n
"
);
printf
(
"Please choose another timing package in config.h.
\n
"
);
exit
(
1
);
}
double
get_counter
()
{
printf
(
"ERROR: You are trying to use a get_counter routine in clock.c
\n
"
);
printf
(
"that has not been implemented yet on this platform.
\n
"
);
printf
(
"Please choose another timing package in config.h.
\n
"
);
exit
(
1
);
}
#endif
/*******************************
* Machine-independent functions
******************************/
double
ovhd
()
{
/* Do it twice to eliminate cache effects */
int
i
;
double
result
;
for
(
i
=
0
;
i
<
2
;
i
++
)
{
start_counter
();
result
=
get_counter
();
}
return
result
;
}
/* $begin mhz */
/* Estimate the clock rate by measuring the cycles that elapse */
/* while sleeping for sleeptime seconds */
double
mhz_full
(
int
verbose
,
int
sleeptime
)
{
double
rate
;
start_counter
();
sleep
(
sleeptime
);
rate
=
get_counter
()
/
(
1e6
*
sleeptime
);
if
(
verbose
)
printf
(
"Processor clock rate ~= %.1f MHz
\n
"
,
rate
);
return
rate
;
}
/* $end mhz */
/* Version using a default sleeptime */
double
mhz
(
int
verbose
)
{
return
mhz_full
(
verbose
,
2
);
}
/** Special counters that compensate for timer interrupt overhead */
static
double
cyc_per_tick
=
0
.
0
;
#define NEVENT 100
#define THRESHOLD 1000
#define RECORDTHRESH 3000
/* Attempt to see how much time is used by timer interrupt */
static
void
callibrate
(
int
verbose
)
{
double
oldt
;
struct
tms
t
;
clock_t
oldc
;
int
e
=
0
;
times
(
&
t
);
oldc
=
t
.
tms_utime
;
start_counter
();
oldt
=
get_counter
();
while
(
e
<
NEVENT
)
{
double
newt
=
get_counter
();
if
(
newt
-
oldt
>=
THRESHOLD
)
{
clock_t
newc
;
times
(
&
t
);
newc
=
t
.
tms_utime
;
if
(
newc
>
oldc
)
{
double
cpt
=
(
newt
-
oldt
)
/
(
newc
-
oldc
);
if
((
cyc_per_tick
==
0
.
0
||
cyc_per_tick
>
cpt
)
&&
cpt
>
RECORDTHRESH
)
cyc_per_tick
=
cpt
;
/*
if (verbose)
printf("Saw event lasting %.0f cycles and %d ticks. Ratio = %f\n",
newt-oldt, (int) (newc-oldc), cpt);
*/
e
++
;
oldc
=
newc
;
}
oldt
=
newt
;
}
}
if
(
verbose
)
printf
(
"Setting cyc_per_tick to %f
\n
"
,
cyc_per_tick
);
}
static
clock_t
start_tick
=
0
;
void
start_comp_counter
()
{
struct
tms
t
;
if
(
cyc_per_tick
==
0
.
0
)
callibrate
(
0
);
times
(
&
t
);
start_tick
=
t
.
tms_utime
;
start_counter
();
}
double
get_comp_counter
()
{
double
time
=
get_counter
();
double
ctime
;
struct
tms
t
;
clock_t
ticks
;
times
(
&
t
);
ticks
=
t
.
tms_utime
-
start_tick
;
ctime
=
time
-
ticks
*
cyc_per_tick
;
/*
printf("Measured %.0f cycles. Ticks = %d. Corrected %.0f cycles\n",
time, (int) ticks, ctime);
*/
return
ctime
;
}
assignment3/malloclab-handout/clock.h
0 → 100644
View file @
01b4e45a
/* Routines for using cycle counter */
/* Start the counter */
void
start_counter
();
/* Get # cycles since counter started */
double
get_counter
();
/* Measure overhead for counter */
double
ovhd
();
/* Determine clock rate of processor (using a default sleeptime) */
double
mhz
(
int
verbose
);
/* Determine clock rate of processor, having more control over accuracy */
double
mhz_full
(
int
verbose
,
int
sleeptime
);
/** Special counters that compensate for timer interrupt overhead */
void
start_comp_counter
();
double
get_comp_counter
();
assignment3/malloclab-handout/config.h
0 → 100644
View file @
01b4e45a
#ifndef __CONFIG_H_
#define __CONFIG_H_
/*
* config.h - malloc lab configuration file
*
* Copyright (c) 2002, R. Bryant and D. O'Hallaron, All rights reserved.
* May not be used, modified, or copied without permission.
*/
/*
* This is the default path where the driver will look for the
* default tracefiles. You can override it at runtime with the -t flag.
*/
#define TRACEDIR "/afs/cs/project/ics2/im/labs/malloclab/traces/"
/*
* This is the list of default tracefiles in TRACEDIR that the driver
* will use for testing. Modify this if you want to add or delete
* traces from the driver's test suite. For example, if you don't want
* your students to implement realloc, you can delete the last two
* traces.
*/
#define DEFAULT_TRACEFILES \
"amptjp-bal.rep",\
"cccp-bal.rep",\
"cp-decl-bal.rep",\
"expr-bal.rep",\
"coalescing-bal.rep",\
"random-bal.rep",\
"random2-bal.rep",\
"binary-bal.rep",\
"binary2-bal.rep",\
"realloc-bal.rep",\
"realloc2-bal.rep"
/*
* This constant gives the estimated performance of the libc malloc
* package using our traces on some reference system, typically the
* same kind of system the students use. Its purpose is to cap the
* contribution of throughput to the performance index. Once the
* students surpass the AVG_LIBC_THRUPUT, they get no further benefit
* to their score. This deters students from building extremely fast,
* but extremely stupid malloc packages.
*/
#define AVG_LIBC_THRUPUT 600E3
/* 600 Kops/sec */
/*
* This constant determines the contributions of space utilization
* (UTIL_WEIGHT) and throughput (1 - UTIL_WEIGHT) to the performance
* index.
*/
#define UTIL_WEIGHT .60
/*
* Alignment requirement in bytes (either 4 or 8)
*/
#define ALIGNMENT 8
/*
* Maximum heap size in bytes
*/
#define MAX_HEAP (20*(1<<20))
/* 20 MB */
/*****************************************************************************
* Set exactly one of these USE_xxx constants to "1" to select a timing method
*****************************************************************************/
#define USE_FCYC 0
/* cycle counter w/K-best scheme (x86 & Alpha only) */
#define USE_ITIMER 0
/* interval timer (any Unix box) */
#define USE_GETTOD 1
/* gettimeofday (any Unix box) */
#endif
/* __CONFIG_H */
assignment3/malloclab-handout/fcyc.c
0 → 100644
View file @
01b4e45a
/*
* fcyc.c - Estimate the time (in CPU cycles) used by a function f
*
* Copyright (c) 2002, R. Bryant and D. O'Hallaron, All rights reserved.
* May not be used, modified, or copied without permission.
*
* Uses the cycle timer routines in clock.c to estimate the
* the time in CPU cycles for a function f.
*/
#include <stdlib.h>
#include <sys/times.h>
#include <stdio.h>
#include "fcyc.h"
#include "clock.h"
/* Default values */
#define K 3
/* Value of K in K-best scheme */
#define MAXSAMPLES 20
/* Give up after MAXSAMPLES */
#define EPSILON 0.01
/* K samples should be EPSILON of each other*/
#define COMPENSATE 0
/* 1-> try to compensate for clock ticks */
#define CLEAR_CACHE 0
/* Clear cache before running test function */
#define CACHE_BYTES (1<<19)
/* Max cache size in bytes */
#define CACHE_BLOCK 32
/* Cache block size in bytes */
static
int
kbest
=
K
;
static
int
maxsamples
=
MAXSAMPLES
;
static
double
epsilon
=
EPSILON
;
static
int
compensate
=
COMPENSATE
;
static
int
clear_cache
=
CLEAR_CACHE
;
static
int
cache_bytes
=
CACHE_BYTES
;
static
int
cache_block
=
CACHE_BLOCK
;
static
int
*
cache_buf
=
NULL
;
static
double
*
values
=
NULL
;
static
int
samplecount
=
0
;
/* for debugging only */
#define KEEP_VALS 0
#define KEEP_SAMPLES 0
#if KEEP_SAMPLES
static
double
*
samples
=
NULL
;
#endif
/*
* init_sampler - Start new sampling process
*/
static
void
init_sampler
()
{
if
(
values
)
free
(
values
);
values
=
calloc
(
kbest
,
sizeof
(
double
));
#if KEEP_SAMPLES
if
(
samples
)
free
(
samples
);
/* Allocate extra for wraparound analysis */
samples
=
calloc
(
maxsamples
+
kbest
,
sizeof
(
double
));
#endif
samplecount
=
0
;
}
/*
* add_sample - Add new sample
*/
static
void
add_sample
(
double
val
)
{
int
pos
=
0
;
if
(
samplecount
<
kbest
)
{
pos
=
samplecount
;
values
[
pos
]
=
val
;
}
else
if
(
val
<
values
[
kbest
-
1
])
{
pos
=
kbest
-
1
;
values
[
pos
]
=
val
;
}
#if KEEP_SAMPLES
samples
[
samplecount
]
=
val
;
#endif
samplecount
++
;
/* Insertion sort */
while
(
pos
>
0
&&
values
[
pos
-
1
]
>
values
[
pos
])
{
double
temp
=
values
[
pos
-
1
];
values
[
pos
-
1
]
=
values
[
pos
];
values
[
pos
]
=
temp
;
pos
--
;
}
}
/*
* has_converged- Have kbest minimum measurements converged within epsilon?
*/
static
int
has_converged
()
{
return
(
samplecount
>=
kbest
)
&&
((
1
+
epsilon
)
*
values
[
0
]
>=
values
[
kbest
-
1
]);
}
/*
* clear - Code to clear cache
*/
static
volatile
int
sink
=
0
;
static
void
clear
()
{
int
x
=
sink
;
int
*
cptr
,
*
cend
;
int
incr
=
cache_block
/
sizeof
(
int
);
if
(
!
cache_buf
)
{
cache_buf
=
malloc
(
cache_bytes
);
if
(
!
cache_buf
)
{
fprintf
(
stderr
,
"Fatal error. Malloc returned null when trying to clear cache
\n
"
);
exit
(
1
);
}
}
cptr
=
(
int
*
)
cache_buf
;
cend
=
cptr
+
cache_bytes
/
sizeof
(
int
);
while
(
cptr
<
cend
)
{
x
+=
*
cptr
;
cptr
+=
incr
;
}
sink
=
x
;
}
/*
* fcyc - Use K-best scheme to estimate the running time of function f
*/
double
fcyc
(
test_funct
f
,
void
*
argp
)
{
double
result
;
init_sampler
();
if
(
compensate
)
{
do
{
double
cyc
;
if
(
clear_cache
)
clear
();
start_comp_counter
();
f
(
argp
);
cyc
=
get_comp_counter
();
add_sample
(
cyc
);
}
while
(
!
has_converged
()
&&
samplecount
<
maxsamples
);
}
else
{
do
{
double
cyc
;
if
(
clear_cache
)
clear
();
start_counter
();
f
(
argp
);
cyc
=
get_counter
();
add_sample
(
cyc
);
}
while
(
!
has_converged
()
&&
samplecount
<
maxsamples
);
}
#ifdef DEBUG
{
int
i
;
printf
(
" %d smallest values: ["
,
kbest
);
for
(
i
=
0
;
i
<
kbest
;
i
++
)
printf
(
"%.0f%s"
,
values
[
i
],
i
==
kbest
-
1
?
"]
\n
"
:
", "
);
}
#endif
result
=
values
[
0
];
#if !KEEP_VALS
free
(
values
);
values
=
NULL
;
#endif
return
result
;
}
/*************************************************************
* Set the various parameters used by the measurement routines
************************************************************/
/*
* set_fcyc_clear_cache - When set, will run code to clear cache
* before each measurement.
* Default = 0
*/
void
set_fcyc_clear_cache
(
int
clear
)
{
clear_cache
=
clear
;
}
/*
* set_fcyc_cache_size - Set size of cache to use when clearing cache
* Default = 1<<19 (512KB)
*/
void
set_fcyc_cache_size
(
int
bytes
)
{
if
(
bytes
!=
cache_bytes
)
{
cache_bytes
=
bytes
;
if
(
cache_buf
)
{
free
(
cache_buf
);
cache_buf
=
NULL
;
}
}
}
/*
* set_fcyc_cache_block - Set size of cache block
* Default = 32
*/
void
set_fcyc_cache_block
(
int
bytes
)
{
cache_block
=
bytes
;
}
/*
* set_fcyc_compensate- When set, will attempt to compensate for
* timer interrupt overhead
* Default = 0
*/
void
set_fcyc_compensate
(
int
compensate_arg
)
{
compensate
=
compensate_arg
;
}
/*
* set_fcyc_k - Value of K in K-best measurement scheme
* Default = 3
*/
void
set_fcyc_k
(
int
k
)
{
kbest
=
k
;
}
/*
* set_fcyc_maxsamples - Maximum number of samples attempting to find
* K-best within some tolerance.
* When exceeded, just return best sample found.
* Default = 20
*/
void
set_fcyc_maxsamples
(
int
maxsamples_arg
)
{
maxsamples
=
maxsamples_arg
;
}
/*
* set_fcyc_epsilon - Tolerance required for K-best
* Default = 0.01
*/
void
set_fcyc_epsilon
(
double
epsilon_arg
)
{
epsilon
=
epsilon_arg
;
}
assignment3/malloclab-handout/fcyc.h
0 → 100644
View file @
01b4e45a
/*
* fcyc.h - prototypes for the routines in fcyc.c that estimate the
* time in CPU cycles used by a test function f
*
* Copyright (c) 2002, R. Bryant and D. O'Hallaron, All rights reserved.
* May not be used, modified, or copied without permission.
*
*/
/* The test function takes a generic pointer as input */
typedef
void
(
*
test_funct
)(
void
*
);
/* Compute number of cycles used by test function f */
double
fcyc
(
test_funct
f
,
void
*
argp
);
/*********************************************************
* Set the various parameters used by measurement routines
*********************************************************/
/*
* set_fcyc_clear_cache - When set, will run code to clear cache
* before each measurement.
* Default = 0
*/
void
set_fcyc_clear_cache
(
int
clear
);
/*
* set_fcyc_cache_size - Set size of cache to use when clearing cache
* Default = 1<<19 (512KB)
*/
void
set_fcyc_cache_size
(
int
bytes
);
/*
* set_fcyc_cache_block - Set size of cache block
* Default = 32
*/
void
set_fcyc_cache_block
(
int
bytes
);
/*
* set_fcyc_compensate- When set, will attempt to compensate for
* timer interrupt overhead
* Default = 0
*/
void
set_fcyc_compensate
(
int
compensate_arg
);
/*
* set_fcyc_k - Value of K in K-best measurement scheme
* Default = 3
*/
void
set_fcyc_k
(
int
k
);
/*
* set_fcyc_maxsamples - Maximum number of samples attempting to find
* K-best within some tolerance.
* When exceeded, just return best sample found.
* Default = 20
*/
void
set_fcyc_maxsamples
(
int
maxsamples_arg
);
/*
* set_fcyc_epsilon - Tolerance required for K-best
* Default = 0.01
*/
void
set_fcyc_epsilon
(
double
epsilon_arg
);
assignment3/malloclab-handout/fsecs.c
0 → 100644
View file @
01b4e45a
/****************************
* High-level timing wrappers
****************************/
#include <stdio.h>
#include "fsecs.h"
#include "fcyc.h"
#include "clock.h"
#include "ftimer.h"
#include "config.h"
static
double
Mhz
;
/* estimated CPU clock frequency */
extern
int
verbose
;
/* -v option in mdriver.c */
/*
* init_fsecs - initialize the timing package
*/
void
init_fsecs
(
void
)
{
Mhz
=
0
;
/* keep gcc -Wall happy */
#if USE_FCYC
if
(
verbose
)
printf
(
"Measuring performance with a cycle counter.
\n
"
);
/* set key parameters for the fcyc package */
set_fcyc_maxsamples
(
20
);
set_fcyc_clear_cache
(
1
);
set_fcyc_compensate
(
1
);
set_fcyc_epsilon
(
0
.
01
);
set_fcyc_k
(
3
);
Mhz
=
mhz
(
verbose
>
0
);
#elif USE_ITIMER
if
(
verbose
)
printf
(
"Measuring performance with the interval timer.
\n
"
);
#elif USE_GETTOD
if
(
verbose
)
printf
(
"Measuring performance with gettimeofday().
\n
"
);
#endif
}
/*
* fsecs - Return the running time of a function f (in seconds)
*/
double
fsecs
(
fsecs_test_funct
f
,
void
*
argp
)
{
#if USE_FCYC
double
cycles
=
fcyc
(
f
,
argp
);
return
cycles
/
(
Mhz
*
1e6
);
#elif USE_ITIMER
return
ftimer_itimer
(
f
,
argp
,
10
);
#elif USE_GETTOD
return
ftimer_gettod
(
f
,
argp
,
10
);
#endif
}
assignment3/malloclab-handout/fsecs.h
0 → 100644
View file @
01b4e45a
typedef
void
(
*
fsecs_test_funct
)(
void
*
);
void
init_fsecs
(
void
);
double
fsecs
(
fsecs_test_funct
f
,
void
*
argp
);
assignment3/malloclab-handout/ftimer.c
0 → 100644
View file @
01b4e45a
/*
* ftimer.c - Estimate the time (in seconds) used by a function f
*
* Copyright (c) 2002, R. Bryant and D. O'Hallaron, All rights reserved.
* May not be used, modified, or copied without permission.
*
* Function timers that estimate the running time (in seconds) of a function f.
* ftimer_itimer: version that uses the interval timer
* ftimer_gettod: version that uses gettimeofday
*/
#include <stdio.h>
#include <sys/time.h>
#include "ftimer.h"
/* function prototypes */
static
void
init_etime
(
void
);
static
double
get_etime
(
void
);
/*
* ftimer_itimer - Use the interval timer to estimate the running time
* of f(argp). Return the average of n runs.
*/
double
ftimer_itimer
(
ftimer_test_funct
f
,
void
*
argp
,
int
n
)
{
double
start
,
tmeas
;
int
i
;
init_etime
();
start
=
get_etime
();
for
(
i
=
0
;
i
<
n
;
i
++
)
f
(
argp
);
tmeas
=
get_etime
()
-
start
;
return
tmeas
/
n
;
}
/*
* ftimer_gettod - Use gettimeofday to estimate the running time of
* f(argp). Return the average of n runs.
*/
double
ftimer_gettod
(
ftimer_test_funct
f
,
void
*
argp
,
int
n
)
{
int
i
;
struct
timeval
stv
,
etv
;
double
diff
;
gettimeofday
(
&
stv
,
NULL
);
for
(
i
=
0
;
i
<
n
;
i
++
)
f
(
argp
);
gettimeofday
(
&
etv
,
NULL
);
diff
=
1E3
*
(
etv
.
tv_sec
-
stv
.
tv_sec
)
+
1E-3
*
(
etv
.
tv_usec
-
stv
.
tv_usec
);
diff
/=
n
;
return
(
1E-3
*
diff
);
}
/*
* Routines for manipulating the Unix interval timer
*/
/* The initial value of the interval timer */
#define MAX_ETIME 86400
/* static variables that hold the initial value of the interval timer */
static
struct
itimerval
first_u
;
/* user time */
static
struct
itimerval
first_r
;
/* real time */
static
struct
itimerval
first_p
;
/* prof time*/
/* init the timer */
static
void
init_etime
(
void
)
{
first_u
.
it_interval
.
tv_sec
=
0
;
first_u
.
it_interval
.
tv_usec
=
0
;
first_u
.
it_value
.
tv_sec
=
MAX_ETIME
;
first_u
.
it_value
.
tv_usec
=
0
;
setitimer
(
ITIMER_VIRTUAL
,
&
first_u
,
NULL
);
first_r
.
it_interval
.
tv_sec
=
0
;
first_r
.
it_interval
.
tv_usec
=
0
;
first_r
.
it_value
.
tv_sec
=
MAX_ETIME
;
first_r
.
it_value
.
tv_usec
=
0
;
setitimer
(
ITIMER_REAL
,
&
first_r
,
NULL
);
first_p
.
it_interval
.
tv_sec
=
0
;
first_p
.
it_interval
.
tv_usec
=
0
;
first_p
.
it_value
.
tv_sec
=
MAX_ETIME
;
first_p
.
it_value
.
tv_usec
=
0
;
setitimer
(
ITIMER_PROF
,
&
first_p
,
NULL
);
}
/* return elapsed real seconds since call to init_etime */
static
double
get_etime
(
void
)
{
struct
itimerval
v_curr
;
struct
itimerval
r_curr
;
struct
itimerval
p_curr
;
getitimer
(
ITIMER_VIRTUAL
,
&
v_curr
);
getitimer
(
ITIMER_REAL
,
&
r_curr
);
getitimer
(
ITIMER_PROF
,
&
p_curr
);
return
(
double
)
((
first_p
.
it_value
.
tv_sec
-
r_curr
.
it_value
.
tv_sec
)
+
(
first_p
.
it_value
.
tv_usec
-
r_curr
.
it_value
.
tv_usec
)
*
1e-6
);
}
assignment3/malloclab-handout/ftimer.h
0 → 100644
View file @
01b4e45a
/*
* Function timers
*/
typedef
void
(
*
ftimer_test_funct
)(
void
*
);
/* Estimate the running time of f(argp) using the Unix interval timer.
Return the average of n runs */
double
ftimer_itimer
(
ftimer_test_funct
f
,
void
*
argp
,
int
n
);
/* Estimate the running time of f(argp) using gettimeofday
Return the average of n runs */
double
ftimer_gettod
(
ftimer_test_funct
f
,
void
*
argp
,
int
n
);
assignment3/malloclab-handout/mdriver.c
0 → 100644
View file @
01b4e45a
/*
* mdriver.c - CS:APP Malloc Lab Driver
*
* Uses a collection of trace files to tests a malloc/free/realloc
* implementation in mm.c.
*
* Copyright (c) 2002, R. Bryant and D. O'Hallaron, All rights reserved.
* May not be used, modified, or copied without permission.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <assert.h>
#include <float.h>
#include <time.h>
#include "mm.h"
#include "memlib.h"
#include "fsecs.h"
#include "config.h"
/**********************
* Constants and macros
**********************/
/* Misc */
#define MAXLINE 1024
/* max string size */
#define HDRLINES 4
/* number of header lines in a trace file */
#define LINENUM(i) (i+5)
/* cnvt trace request nums to linenums (origin 1) */
/* Returns true if p is ALIGNMENT-byte aligned */
#define IS_ALIGNED(p) ((((unsigned int)(p)) % ALIGNMENT) == 0)
/******************************
* The key compound data types
*****************************/
/* Records the extent of each block's payload */
typedef
struct
range_t
{
char
*
lo
;
/* low payload address */
char
*
hi
;
/* high payload address */
struct
range_t
*
next
;
/* next list element */
}
range_t
;
/* Characterizes a single trace operation (allocator request) */
typedef
struct
{
enum
{
ALLOC
,
FREE
,
REALLOC
}
type
;
/* type of request */
int
index
;
/* index for free() to use later */
int
size
;
/* byte size of alloc/realloc request */
}
traceop_t
;
/* Holds the information for one trace file*/
typedef
struct
{
int
sugg_heapsize
;
/* suggested heap size (unused) */
int
num_ids
;
/* number of alloc/realloc ids */
int
num_ops
;
/* number of distinct requests */
int
weight
;
/* weight for this trace (unused) */
traceop_t
*
ops
;
/* array of requests */
char
**
blocks
;
/* array of ptrs returned by malloc/realloc... */
size_t
*
block_sizes
;
/* ... and a corresponding array of payload sizes */
}
trace_t
;
/*
* Holds the params to the xxx_speed functions, which are timed by fcyc.
* This struct is necessary because fcyc accepts only a pointer array
* as input.
*/
typedef
struct
{
trace_t
*
trace
;
range_t
*
ranges
;
}
speed_t
;
/* Summarizes the important stats for some malloc function on some trace */
typedef
struct
{
/* defined for both libc malloc and student malloc package (mm.c) */
double
ops
;
/* number of ops (malloc/free/realloc) in the trace */
int
valid
;
/* was the trace processed correctly by the allocator? */
double
secs
;
/* number of secs needed to run the trace */
/* defined only for the student malloc package */
double
util
;
/* space utilization for this trace (always 0 for libc) */
/* Note: secs and util are only defined if valid is true */
}
stats_t
;
/********************
* Global variables
*******************/
int
verbose
=
0
;
/* global flag for verbose output */
static
int
errors
=
0
;
/* number of errs found when running student malloc */
char
msg
[
MAXLINE
];
/* for whenever we need to compose an error message */
/* Directory where default tracefiles are found */
static
char
tracedir
[
MAXLINE
]
=
TRACEDIR
;
/* The filenames of the default tracefiles */
static
char
*
default_tracefiles
[]
=
{
DEFAULT_TRACEFILES
,
NULL
};
/*********************
* Function prototypes
*********************/
/* these functions manipulate range lists */
static
int
add_range
(
range_t
**
ranges
,
char
*
lo
,
int
size
,
int
tracenum
,
int
opnum
);
static
void
remove_range
(
range_t
**
ranges
,
char
*
lo
);
static
void
clear_ranges
(
range_t
**
ranges
);
/* These functions read, allocate, and free storage for traces */
static
trace_t
*
read_trace
(
char
*
tracedir
,
char
*
filename
);
static
void
free_trace
(
trace_t
*
trace
);
/* Routines for evaluating the correctness and speed of libc malloc */
static
int
eval_libc_valid
(
trace_t
*
trace
,
int
tracenum
);
static
void
eval_libc_speed
(
void
*
ptr
);
/* Routines for evaluating correctnes, space utilization, and speed
of the student's malloc package in mm.c */
static
int
eval_mm_valid
(
trace_t
*
trace
,
int
tracenum
,
range_t
**
ranges
);
static
double
eval_mm_util
(
trace_t
*
trace
,
int
tracenum
,
range_t
**
ranges
);
static
void
eval_mm_speed
(
void
*
ptr
);
/* Various helper routines */
static
void
printresults
(
int
n
,
stats_t
*
stats
);
static
void
usage
(
void
);
static
void
unix_error
(
char
*
msg
);
static
void
malloc_error
(
int
tracenum
,
int
opnum
,
char
*
msg
);
static
void
app_error
(
char
*
msg
);
/**************
* Main routine
**************/
int
main
(
int
argc
,
char
**
argv
)
{
int
i
;
char
c
;
char
**
tracefiles
=
NULL
;
/* null-terminated array of trace file names */
int
num_tracefiles
=
0
;
/* the number of traces in that array */
trace_t
*
trace
=
NULL
;
/* stores a single trace file in memory */
range_t
*
ranges
=
NULL
;
/* keeps track of block extents for one trace */
stats_t
*
libc_stats
=
NULL
;
/* libc stats for each trace */
stats_t
*
mm_stats
=
NULL
;
/* mm (i.e. student) stats for each trace */
speed_t
speed_params
;
/* input parameters to the xx_speed routines */
int
team_check
=
1
;
/* If set, check team structure (reset by -a) */
int
run_libc
=
0
;
/* If set, run libc malloc (set by -l) */
int
autograder
=
0
;
/* If set, emit summary info for autograder (-g) */
/* temporaries used to compute the performance index */
double
secs
,
ops
,
util
,
avg_mm_util
,
avg_mm_throughput
,
p1
,
p2
,
perfindex
;
int
numcorrect
;
/*
* Read and interpret the command line arguments
*/
while
((
c
=
getopt
(
argc
,
argv
,
"f:t:hvVgal"
))
!=
EOF
)
{
switch
(
c
)
{
case
'g'
:
/* Generate summary info for the autograder */
autograder
=
1
;
break
;
case
'f'
:
/* Use one specific trace file only (relative to curr dir) */
num_tracefiles
=
1
;
if
((
tracefiles
=
realloc
(
tracefiles
,
2
*
sizeof
(
char
*
)))
==
NULL
)
unix_error
(
"ERROR: realloc failed in main"
);
strcpy
(
tracedir
,
"./"
);
tracefiles
[
0
]
=
strdup
(
optarg
);
tracefiles
[
1
]
=
NULL
;
break
;
case
't'
:
/* Directory where the traces are located */
if
(
num_tracefiles
==
1
)
/* ignore if -f already encountered */
break
;
strcpy
(
tracedir
,
optarg
);
if
(
tracedir
[
strlen
(
tracedir
)
-
1
]
!=
'/'
)
strcat
(
tracedir
,
"/"
);
/* path always ends with "/" */
break
;
case
'a'
:
/* Don't check team structure */
team_check
=
0
;
break
;
case
'l'
:
/* Run libc malloc */
run_libc
=
1
;
break
;
case
'v'
:
/* Print per-trace performance breakdown */
verbose
=
1
;
break
;
case
'V'
:
/* Be more verbose than -v */
verbose
=
2
;
break
;
case
'h'
:
/* Print this message */
usage
();
exit
(
0
);
default:
usage
();
exit
(
1
);
}
}
/*
* Check and print team info
*/
if
(
team_check
)
{
/* Students must fill in their team information */
if
(
!
strcmp
(
team
.
teamname
,
""
))
{
printf
(
"ERROR: Please provide the information about your team in mm.c.
\n
"
);
exit
(
1
);
}
else
printf
(
"Team Name:%s
\n
"
,
team
.
teamname
);
if
((
*
team
.
name1
==
'\0'
)
||
(
*
team
.
id1
==
'\0'
))
{
printf
(
"ERROR. You must fill in all team member 1 fields!
\n
"
);
exit
(
1
);
}
else
printf
(
"Member 1 :%s:%s
\n
"
,
team
.
name1
,
team
.
id1
);
if
(((
*
team
.
name2
!=
'\0'
)
&&
(
*
team
.
id2
==
'\0'
))
||
((
*
team
.
name2
==
'\0'
)
&&
(
*
team
.
id2
!=
'\0'
)))
{
printf
(
"ERROR. You must fill in all or none of the team member 2 ID fields!
\n
"
);
exit
(
1
);
}
else
if
(
*
team
.
name2
!=
'\0'
)
printf
(
"Member 2 :%s:%s
\n
"
,
team
.
name2
,
team
.
id2
);
}
/*
* If no -f command line arg, then use the entire set of tracefiles
* defined in default_traces[]
*/
if
(
tracefiles
==
NULL
)
{
tracefiles
=
default_tracefiles
;
num_tracefiles
=
sizeof
(
default_tracefiles
)
/
sizeof
(
char
*
)
-
1
;
printf
(
"Using default tracefiles in %s
\n
"
,
tracedir
);
}
/* Initialize the timing package */
init_fsecs
();
/*
* Optionally run and evaluate the libc malloc package
*/
if
(
run_libc
)
{
if
(
verbose
>
1
)
printf
(
"
\n
Testing libc malloc
\n
"
);
/* Allocate libc stats array, with one stats_t struct per tracefile */
libc_stats
=
(
stats_t
*
)
calloc
(
num_tracefiles
,
sizeof
(
stats_t
));
if
(
libc_stats
==
NULL
)
unix_error
(
"libc_stats calloc in main failed"
);
/* Evaluate the libc malloc package using the K-best scheme */
for
(
i
=
0
;
i
<
num_tracefiles
;
i
++
)
{
trace
=
read_trace
(
tracedir
,
tracefiles
[
i
]);
libc_stats
[
i
].
ops
=
trace
->
num_ops
;
if
(
verbose
>
1
)
printf
(
"Checking libc malloc for correctness, "
);
libc_stats
[
i
].
valid
=
eval_libc_valid
(
trace
,
i
);
if
(
libc_stats
[
i
].
valid
)
{
speed_params
.
trace
=
trace
;
if
(
verbose
>
1
)
printf
(
"and performance.
\n
"
);
libc_stats
[
i
].
secs
=
fsecs
(
eval_libc_speed
,
&
speed_params
);
}
free_trace
(
trace
);
}
/* Display the libc results in a compact table */
if
(
verbose
)
{
printf
(
"
\n
Results for libc malloc:
\n
"
);
printresults
(
num_tracefiles
,
libc_stats
);
}
}
/*
* Always run and evaluate the student's mm package
*/
if
(
verbose
>
1
)
printf
(
"
\n
Testing mm malloc
\n
"
);
/* Allocate the mm stats array, with one stats_t struct per tracefile */
mm_stats
=
(
stats_t
*
)
calloc
(
num_tracefiles
,
sizeof
(
stats_t
));
if
(
mm_stats
==
NULL
)
unix_error
(
"mm_stats calloc in main failed"
);
/* Initialize the simulated memory system in memlib.c */
mem_init
();
/* Evaluate student's mm malloc package using the K-best scheme */
for
(
i
=
0
;
i
<
num_tracefiles
;
i
++
)
{
trace
=
read_trace
(
tracedir
,
tracefiles
[
i
]);
mm_stats
[
i
].
ops
=
trace
->
num_ops
;
if
(
verbose
>
1
)
printf
(
"Checking mm_malloc for correctness, "
);
mm_stats
[
i
].
valid
=
eval_mm_valid
(
trace
,
i
,
&
ranges
);
if
(
mm_stats
[
i
].
valid
)
{
if
(
verbose
>
1
)
printf
(
"efficiency, "
);
mm_stats
[
i
].
util
=
eval_mm_util
(
trace
,
i
,
&
ranges
);
speed_params
.
trace
=
trace
;
speed_params
.
ranges
=
ranges
;
if
(
verbose
>
1
)
printf
(
"and performance.
\n
"
);
mm_stats
[
i
].
secs
=
fsecs
(
eval_mm_speed
,
&
speed_params
);
}
free_trace
(
trace
);
}
/* Display the mm results in a compact table */
if
(
verbose
)
{
printf
(
"
\n
Results for mm malloc:
\n
"
);
printresults
(
num_tracefiles
,
mm_stats
);
printf
(
"
\n
"
);
}
/*
* Accumulate the aggregate statistics for the student's mm package
*/
secs
=
0
;
ops
=
0
;
util
=
0
;
numcorrect
=
0
;
for
(
i
=
0
;
i
<
num_tracefiles
;
i
++
)
{
secs
+=
mm_stats
[
i
].
secs
;
ops
+=
mm_stats
[
i
].
ops
;
util
+=
mm_stats
[
i
].
util
;
if
(
mm_stats
[
i
].
valid
)
numcorrect
++
;
}
avg_mm_util
=
util
/
num_tracefiles
;
/*
* Compute and print the performance index
*/
if
(
errors
==
0
)
{
avg_mm_throughput
=
ops
/
secs
;
p1
=
UTIL_WEIGHT
*
avg_mm_util
;
if
(
avg_mm_throughput
>
AVG_LIBC_THRUPUT
)
{
p2
=
(
double
)(
1
.
0
-
UTIL_WEIGHT
);
}
else
{
p2
=
((
double
)
(
1
.
0
-
UTIL_WEIGHT
))
*
(
avg_mm_throughput
/
AVG_LIBC_THRUPUT
);
}
perfindex
=
(
p1
+
p2
)
*
100
.
0
;
printf
(
"Perf index = %.0f (util) + %.0f (thru) = %.0f/100
\n
"
,
p1
*
100
,
p2
*
100
,
perfindex
);
}
else
{
/* There were errors */
perfindex
=
0
.
0
;
printf
(
"Terminated with %d errors
\n
"
,
errors
);
}
if
(
autograder
)
{
printf
(
"correct:%d
\n
"
,
numcorrect
);
printf
(
"perfidx:%.0f
\n
"
,
perfindex
);
}
exit
(
0
);
}
/*****************************************************************
* The following routines manipulate the range list, which keeps
* track of the extent of every allocated block payload. We use the
* range list to detect any overlapping allocated blocks.
****************************************************************/
/*
* add_range - As directed by request opnum in trace tracenum,
* we've just called the student's mm_malloc to allocate a block of
* size bytes at addr lo. After checking the block for correctness,
* we create a range struct for this block and add it to the range list.
*/
static
int
add_range
(
range_t
**
ranges
,
char
*
lo
,
int
size
,
int
tracenum
,
int
opnum
)
{
char
*
hi
=
lo
+
size
-
1
;
range_t
*
p
;
char
msg
[
MAXLINE
];
assert
(
size
>
0
);
/* Payload addresses must be ALIGNMENT-byte aligned */
if
(
!
IS_ALIGNED
(
lo
))
{
sprintf
(
msg
,
"Payload address (%p) not aligned to %d bytes"
,
lo
,
ALIGNMENT
);
malloc_error
(
tracenum
,
opnum
,
msg
);
return
0
;
}
/* The payload must lie within the extent of the heap */
if
((
lo
<
(
char
*
)
mem_heap_lo
())
||
(
lo
>
(
char
*
)
mem_heap_hi
())
||
(
hi
<
(
char
*
)
mem_heap_lo
())
||
(
hi
>
(
char
*
)
mem_heap_hi
()))
{
sprintf
(
msg
,
"Payload (%p:%p) lies outside heap (%p:%p)"
,
lo
,
hi
,
mem_heap_lo
(),
mem_heap_hi
());
malloc_error
(
tracenum
,
opnum
,
msg
);
return
0
;
}
/* The payload must not overlap any other payloads */
for
(
p
=
*
ranges
;
p
!=
NULL
;
p
=
p
->
next
)
{
if
((
lo
>=
p
->
lo
&&
lo
<=
p
->
hi
)
||
(
hi
>=
p
->
lo
&&
hi
<=
p
->
hi
))
{
sprintf
(
msg
,
"Payload (%p:%p) overlaps another payload (%p:%p)
\n
"
,
lo
,
hi
,
p
->
lo
,
p
->
hi
);
malloc_error
(
tracenum
,
opnum
,
msg
);
return
0
;
}
}
/*
* Everything looks OK, so remember the extent of this block
* by creating a range struct and adding it the range list.
*/
if
((
p
=
(
range_t
*
)
malloc
(
sizeof
(
range_t
)))
==
NULL
)
unix_error
(
"malloc error in add_range"
);
p
->
next
=
*
ranges
;
p
->
lo
=
lo
;
p
->
hi
=
hi
;
*
ranges
=
p
;
return
1
;
}
/*
* remove_range - Free the range record of block whose payload starts at lo
*/
static
void
remove_range
(
range_t
**
ranges
,
char
*
lo
)
{
range_t
*
p
;
range_t
**
prevpp
=
ranges
;
int
size
;
for
(
p
=
*
ranges
;
p
!=
NULL
;
p
=
p
->
next
)
{
if
(
p
->
lo
==
lo
)
{
*
prevpp
=
p
->
next
;
size
=
p
->
hi
-
p
->
lo
+
1
;
free
(
p
);
break
;
}
prevpp
=
&
(
p
->
next
);
}
}
/*
* clear_ranges - free all of the range records for a trace
*/
static
void
clear_ranges
(
range_t
**
ranges
)
{
range_t
*
p
;
range_t
*
pnext
;
for
(
p
=
*
ranges
;
p
!=
NULL
;
p
=
pnext
)
{
pnext
=
p
->
next
;
free
(
p
);
}
*
ranges
=
NULL
;
}
/**********************************************
* The following routines manipulate tracefiles
*********************************************/
/*
* read_trace - read a trace file and store it in memory
*/
static
trace_t
*
read_trace
(
char
*
tracedir
,
char
*
filename
)
{
FILE
*
tracefile
;
trace_t
*
trace
;
char
type
[
MAXLINE
];
char
path
[
MAXLINE
];
unsigned
index
,
size
;
unsigned
max_index
=
0
;
unsigned
op_index
;
if
(
verbose
>
1
)
printf
(
"Reading tracefile: %s
\n
"
,
filename
);
/* Allocate the trace record */
if
((
trace
=
(
trace_t
*
)
malloc
(
sizeof
(
trace_t
)))
==
NULL
)
unix_error
(
"malloc 1 failed in read_trance"
);
/* Read the trace file header */
strcpy
(
path
,
tracedir
);
strcat
(
path
,
filename
);
if
((
tracefile
=
fopen
(
path
,
"r"
))
==
NULL
)
{
sprintf
(
msg
,
"Could not open %s in read_trace"
,
path
);
unix_error
(
msg
);
}
fscanf
(
tracefile
,
"%d"
,
&
(
trace
->
sugg_heapsize
));
/* not used */
fscanf
(
tracefile
,
"%d"
,
&
(
trace
->
num_ids
));
fscanf
(
tracefile
,
"%d"
,
&
(
trace
->
num_ops
));
fscanf
(
tracefile
,
"%d"
,
&
(
trace
->
weight
));
/* not used */
/* We'll store each request line in the trace in this array */
if
((
trace
->
ops
=
(
traceop_t
*
)
malloc
(
trace
->
num_ops
*
sizeof
(
traceop_t
)))
==
NULL
)
unix_error
(
"malloc 2 failed in read_trace"
);
/* We'll keep an array of pointers to the allocated blocks here... */
if
((
trace
->
blocks
=
(
char
**
)
malloc
(
trace
->
num_ids
*
sizeof
(
char
*
)))
==
NULL
)
unix_error
(
"malloc 3 failed in read_trace"
);
/* ... along with the corresponding byte sizes of each block */
if
((
trace
->
block_sizes
=
(
size_t
*
)
malloc
(
trace
->
num_ids
*
sizeof
(
size_t
)))
==
NULL
)
unix_error
(
"malloc 4 failed in read_trace"
);
/* read every request line in the trace file */
index
=
0
;
op_index
=
0
;
while
(
fscanf
(
tracefile
,
"%s"
,
type
)
!=
EOF
)
{
switch
(
type
[
0
])
{
case
'a'
:
fscanf
(
tracefile
,
"%u %u"
,
&
index
,
&
size
);
trace
->
ops
[
op_index
].
type
=
ALLOC
;
trace
->
ops
[
op_index
].
index
=
index
;
trace
->
ops
[
op_index
].
size
=
size
;
max_index
=
(
index
>
max_index
)
?
index
:
max_index
;
break
;
case
'r'
:
fscanf
(
tracefile
,
"%u %u"
,
&
index
,
&
size
);
trace
->
ops
[
op_index
].
type
=
REALLOC
;
trace
->
ops
[
op_index
].
index
=
index
;
trace
->
ops
[
op_index
].
size
=
size
;
max_index
=
(
index
>
max_index
)
?
index
:
max_index
;
break
;
case
'f'
:
fscanf
(
tracefile
,
"%ud"
,
&
index
);
trace
->
ops
[
op_index
].
type
=
FREE
;
trace
->
ops
[
op_index
].
index
=
index
;
break
;
default:
printf
(
"Bogus type character (%c) in tracefile %s
\n
"
,
type
[
0
],
path
);
exit
(
1
);
}
op_index
++
;
}
fclose
(
tracefile
);
assert
(
max_index
==
trace
->
num_ids
-
1
);
assert
(
trace
->
num_ops
==
op_index
);
return
trace
;
}
/*
* free_trace - Free the trace record and the three arrays it points
* to, all of which were allocated in read_trace().
*/
void
free_trace
(
trace_t
*
trace
)
{
free
(
trace
->
ops
);
/* free the three arrays... */
free
(
trace
->
blocks
);
free
(
trace
->
block_sizes
);
free
(
trace
);
/* and the trace record itself... */
}
/**********************************************************************
* The following functions evaluate the correctness, space utilization,
* and throughput of the libc and mm malloc packages.
**********************************************************************/
/*
* eval_mm_valid - Check the mm malloc package for correctness
*/
static
int
eval_mm_valid
(
trace_t
*
trace
,
int
tracenum
,
range_t
**
ranges
)
{
int
i
,
j
;
int
index
;
int
size
;
int
oldsize
;
char
*
newp
;
char
*
oldp
;
char
*
p
;
/* Reset the heap and free any records in the range list */
mem_reset_brk
();
clear_ranges
(
ranges
);
/* Call the mm package's init function */
if
(
mm_init
()
<
0
)
{
malloc_error
(
tracenum
,
0
,
"mm_init failed."
);
return
0
;
}
/* Interpret each operation in the trace in order */
for
(
i
=
0
;
i
<
trace
->
num_ops
;
i
++
)
{
index
=
trace
->
ops
[
i
].
index
;
size
=
trace
->
ops
[
i
].
size
;
switch
(
trace
->
ops
[
i
].
type
)
{
case
ALLOC
:
/* mm_malloc */
/* Call the student's malloc */
if
((
p
=
mm_malloc
(
size
))
==
NULL
)
{
malloc_error
(
tracenum
,
i
,
"mm_malloc failed."
);
return
0
;
}
/*
* Test the range of the new block for correctness and add it
* to the range list if OK. The block must be be aligned properly,
* and must not overlap any currently allocated block.
*/
if
(
add_range
(
ranges
,
p
,
size
,
tracenum
,
i
)
==
0
)
return
0
;
/* ADDED: cgw
* fill range with low byte of index. This will be used later
* if we realloc the block and wish to make sure that the old
* data was copied to the new block
*/
memset
(
p
,
index
&
0xFF
,
size
);
/* Remember region */
trace
->
blocks
[
index
]
=
p
;
trace
->
block_sizes
[
index
]
=
size
;
break
;
case
REALLOC
:
/* mm_realloc */
/* Call the student's realloc */
oldp
=
trace
->
blocks
[
index
];
if
((
newp
=
mm_realloc
(
oldp
,
size
))
==
NULL
)
{
malloc_error
(
tracenum
,
i
,
"mm_realloc failed."
);
return
0
;
}
/* Remove the old region from the range list */
remove_range
(
ranges
,
oldp
);
/* Check new block for correctness and add it to range list */
if
(
add_range
(
ranges
,
newp
,
size
,
tracenum
,
i
)
==
0
)
return
0
;
/* ADDED: cgw
* Make sure that the new block contains the data from the old
* block and then fill in the new block with the low order byte
* of the new index
*/
oldsize
=
trace
->
block_sizes
[
index
];
if
(
size
<
oldsize
)
oldsize
=
size
;
for
(
j
=
0
;
j
<
oldsize
;
j
++
)
{
if
(
newp
[
j
]
!=
(
index
&
0xFF
))
{
malloc_error
(
tracenum
,
i
,
"mm_realloc did not preserve the "
"data from old block"
);
return
0
;
}
}
memset
(
newp
,
index
&
0xFF
,
size
);
/* Remember region */
trace
->
blocks
[
index
]
=
newp
;
trace
->
block_sizes
[
index
]
=
size
;
break
;
case
FREE
:
/* mm_free */
/* Remove region from list and call student's free function */
p
=
trace
->
blocks
[
index
];
remove_range
(
ranges
,
p
);
mm_free
(
p
);
break
;
default:
app_error
(
"Nonexistent request type in eval_mm_valid"
);
}
}
/* As far as we know, this is a valid malloc package */
return
1
;
}
/*
* eval_mm_util - Evaluate the space utilization of the student's package
* The idea is to remember the high water mark "hwm" of the heap for
* an optimal allocator, i.e., no gaps and no internal fragmentation.
* Utilization is the ratio hwm/heapsize, where heapsize is the
* size of the heap in bytes after running the student's malloc
* package on the trace. Note that our implementation of mem_sbrk()
* doesn't allow the students to decrement the brk pointer, so brk
* is always the high water mark of the heap.
*
*/
static
double
eval_mm_util
(
trace_t
*
trace
,
int
tracenum
,
range_t
**
ranges
)
{
int
i
;
int
index
;
int
size
,
newsize
,
oldsize
;
int
max_total_size
=
0
;
int
total_size
=
0
;
char
*
p
;
char
*
newp
,
*
oldp
;
/* initialize the heap and the mm malloc package */
mem_reset_brk
();
if
(
mm_init
()
<
0
)
app_error
(
"mm_init failed in eval_mm_util"
);
for
(
i
=
0
;
i
<
trace
->
num_ops
;
i
++
)
{
switch
(
trace
->
ops
[
i
].
type
)
{
case
ALLOC
:
/* mm_alloc */
index
=
trace
->
ops
[
i
].
index
;
size
=
trace
->
ops
[
i
].
size
;
if
((
p
=
mm_malloc
(
size
))
==
NULL
)
app_error
(
"mm_malloc failed in eval_mm_util"
);
/* Remember region and size */
trace
->
blocks
[
index
]
=
p
;
trace
->
block_sizes
[
index
]
=
size
;
/* Keep track of current total size
* of all allocated blocks */
total_size
+=
size
;
/* Update statistics */
max_total_size
=
(
total_size
>
max_total_size
)
?
total_size
:
max_total_size
;
break
;
case
REALLOC
:
/* mm_realloc */
index
=
trace
->
ops
[
i
].
index
;
newsize
=
trace
->
ops
[
i
].
size
;
oldsize
=
trace
->
block_sizes
[
index
];
oldp
=
trace
->
blocks
[
index
];
if
((
newp
=
mm_realloc
(
oldp
,
newsize
))
==
NULL
)
app_error
(
"mm_realloc failed in eval_mm_util"
);
/* Remember region and size */
trace
->
blocks
[
index
]
=
newp
;
trace
->
block_sizes
[
index
]
=
newsize
;
/* Keep track of current total size
* of all allocated blocks */
total_size
+=
(
newsize
-
oldsize
);
/* Update statistics */
max_total_size
=
(
total_size
>
max_total_size
)
?
total_size
:
max_total_size
;
break
;
case
FREE
:
/* mm_free */
index
=
trace
->
ops
[
i
].
index
;
size
=
trace
->
block_sizes
[
index
];
p
=
trace
->
blocks
[
index
];
mm_free
(
p
);
/* Keep track of current total size
* of all allocated blocks */
total_size
-=
size
;
break
;
default:
app_error
(
"Nonexistent request type in eval_mm_util"
);
}
}
return
((
double
)
max_total_size
/
(
double
)
mem_heapsize
());
}
/*
* eval_mm_speed - This is the function that is used by fcyc()
* to measure the running time of the mm malloc package.
*/
static
void
eval_mm_speed
(
void
*
ptr
)
{
int
i
,
index
,
size
,
newsize
;
char
*
p
,
*
newp
,
*
oldp
,
*
block
;
trace_t
*
trace
=
((
speed_t
*
)
ptr
)
->
trace
;
/* Reset the heap and initialize the mm package */
mem_reset_brk
();
if
(
mm_init
()
<
0
)
app_error
(
"mm_init failed in eval_mm_speed"
);
/* Interpret each trace request */
for
(
i
=
0
;
i
<
trace
->
num_ops
;
i
++
)
switch
(
trace
->
ops
[
i
].
type
)
{
case
ALLOC
:
/* mm_malloc */
index
=
trace
->
ops
[
i
].
index
;
size
=
trace
->
ops
[
i
].
size
;
if
((
p
=
mm_malloc
(
size
))
==
NULL
)
app_error
(
"mm_malloc error in eval_mm_speed"
);
trace
->
blocks
[
index
]
=
p
;
break
;
case
REALLOC
:
/* mm_realloc */
index
=
trace
->
ops
[
i
].
index
;
newsize
=
trace
->
ops
[
i
].
size
;
oldp
=
trace
->
blocks
[
index
];
if
((
newp
=
mm_realloc
(
oldp
,
newsize
))
==
NULL
)
app_error
(
"mm_realloc error in eval_mm_speed"
);
trace
->
blocks
[
index
]
=
newp
;
break
;
case
FREE
:
/* mm_free */
index
=
trace
->
ops
[
i
].
index
;
block
=
trace
->
blocks
[
index
];
mm_free
(
block
);
break
;
default:
app_error
(
"Nonexistent request type in eval_mm_valid"
);
}
}
/*
* eval_libc_valid - We run this function to make sure that the
* libc malloc can run to completion on the set of traces.
* We'll be conservative and terminate if any libc malloc call fails.
*
*/
static
int
eval_libc_valid
(
trace_t
*
trace
,
int
tracenum
)
{
int
i
,
newsize
;
char
*
p
,
*
newp
,
*
oldp
;
for
(
i
=
0
;
i
<
trace
->
num_ops
;
i
++
)
{
switch
(
trace
->
ops
[
i
].
type
)
{
case
ALLOC
:
/* malloc */
if
((
p
=
malloc
(
trace
->
ops
[
i
].
size
))
==
NULL
)
{
malloc_error
(
tracenum
,
i
,
"libc malloc failed"
);
unix_error
(
"System message"
);
}
trace
->
blocks
[
trace
->
ops
[
i
].
index
]
=
p
;
break
;
case
REALLOC
:
/* realloc */
newsize
=
trace
->
ops
[
i
].
size
;
oldp
=
trace
->
blocks
[
trace
->
ops
[
i
].
index
];
if
((
newp
=
realloc
(
oldp
,
newsize
))
==
NULL
)
{
malloc_error
(
tracenum
,
i
,
"libc realloc failed"
);
unix_error
(
"System message"
);
}
trace
->
blocks
[
trace
->
ops
[
i
].
index
]
=
newp
;
break
;
case
FREE
:
/* free */
free
(
trace
->
blocks
[
trace
->
ops
[
i
].
index
]);
break
;
default:
app_error
(
"invalid operation type in eval_libc_valid"
);
}
}
return
1
;
}
/*
* eval_libc_speed - This is the function that is used by fcyc() to
* measure the running time of the libc malloc package on the set
* of traces.
*/
static
void
eval_libc_speed
(
void
*
ptr
)
{
int
i
;
int
index
,
size
,
newsize
;
char
*
p
,
*
newp
,
*
oldp
,
*
block
;
trace_t
*
trace
=
((
speed_t
*
)
ptr
)
->
trace
;
for
(
i
=
0
;
i
<
trace
->
num_ops
;
i
++
)
{
switch
(
trace
->
ops
[
i
].
type
)
{
case
ALLOC
:
/* malloc */
index
=
trace
->
ops
[
i
].
index
;
size
=
trace
->
ops
[
i
].
size
;
if
((
p
=
malloc
(
size
))
==
NULL
)
unix_error
(
"malloc failed in eval_libc_speed"
);
trace
->
blocks
[
index
]
=
p
;
break
;
case
REALLOC
:
/* realloc */
index
=
trace
->
ops
[
i
].
index
;
newsize
=
trace
->
ops
[
i
].
size
;
oldp
=
trace
->
blocks
[
index
];
if
((
newp
=
realloc
(
oldp
,
newsize
))
==
NULL
)
unix_error
(
"realloc failed in eval_libc_speed
\n
"
);
trace
->
blocks
[
index
]
=
newp
;
break
;
case
FREE
:
/* free */
index
=
trace
->
ops
[
i
].
index
;
block
=
trace
->
blocks
[
index
];
free
(
block
);
break
;
}
}
}
/*************************************
* Some miscellaneous helper routines
************************************/
/*
* printresults - prints a performance summary for some malloc package
*/
static
void
printresults
(
int
n
,
stats_t
*
stats
)
{
int
i
;
double
secs
=
0
;
double
ops
=
0
;
double
util
=
0
;
/* Print the individual results for each trace */
printf
(
"%5s%7s %5s%8s%10s%6s
\n
"
,
"trace"
,
" valid"
,
"util"
,
"ops"
,
"secs"
,
"Kops"
);
for
(
i
=
0
;
i
<
n
;
i
++
)
{
if
(
stats
[
i
].
valid
)
{
printf
(
"%2d%10s%5.0f%%%8.0f%10.6f%6.0f
\n
"
,
i
,
"yes"
,
stats
[
i
].
util
*
100
.
0
,
stats
[
i
].
ops
,
stats
[
i
].
secs
,
(
stats
[
i
].
ops
/
1e3
)
/
stats
[
i
].
secs
);
secs
+=
stats
[
i
].
secs
;
ops
+=
stats
[
i
].
ops
;
util
+=
stats
[
i
].
util
;
}
else
{
printf
(
"%2d%10s%6s%8s%10s%6s
\n
"
,
i
,
"no"
,
"-"
,
"-"
,
"-"
,
"-"
);
}
}
/* Print the aggregate results for the set of traces */
if
(
errors
==
0
)
{
printf
(
"%12s%5.0f%%%8.0f%10.6f%6.0f
\n
"
,
"Total "
,
(
util
/
n
)
*
100
.
0
,
ops
,
secs
,
(
ops
/
1e3
)
/
secs
);
}
else
{
printf
(
"%12s%6s%8s%10s%6s
\n
"
,
"Total "
,
"-"
,
"-"
,
"-"
,
"-"
);
}
}
/*
* app_error - Report an arbitrary application error
*/
void
app_error
(
char
*
msg
)
{
printf
(
"%s
\n
"
,
msg
);
exit
(
1
);
}
/*
* unix_error - Report a Unix-style error
*/
void
unix_error
(
char
*
msg
)
{
printf
(
"%s: %s
\n
"
,
msg
,
strerror
(
errno
));
exit
(
1
);
}
/*
* malloc_error - Report an error returned by the mm_malloc package
*/
void
malloc_error
(
int
tracenum
,
int
opnum
,
char
*
msg
)
{
errors
++
;
printf
(
"ERROR [trace %d, line %d]: %s
\n
"
,
tracenum
,
LINENUM
(
opnum
),
msg
);
}
/*
* usage - Explain the command line arguments
*/
static
void
usage
(
void
)
{
fprintf
(
stderr
,
"Usage: mdriver [-hvVal] [-f <file>] [-t <dir>]
\n
"
);
fprintf
(
stderr
,
"Options
\n
"
);
fprintf
(
stderr
,
"
\t
-a Don't check the team structure.
\n
"
);
fprintf
(
stderr
,
"
\t
-f <file> Use <file> as the trace file.
\n
"
);
fprintf
(
stderr
,
"
\t
-g Generate summary info for autograder.
\n
"
);
fprintf
(
stderr
,
"
\t
-h Print this message.
\n
"
);
fprintf
(
stderr
,
"
\t
-l Run libc malloc as well.
\n
"
);
fprintf
(
stderr
,
"
\t
-t <dir> Directory to find default traces.
\n
"
);
fprintf
(
stderr
,
"
\t
-v Print per-trace performance breakdowns.
\n
"
);
fprintf
(
stderr
,
"
\t
-V Print additional debug info.
\n
"
);
}
assignment3/malloclab-handout/memlib.c
0 → 100644
View file @
01b4e45a
/*
* memlib.c - a module that simulates the memory system. Needed because it
* allows us to interleave calls from the student's malloc package
* with the system's malloc package in libc.
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <sys/mman.h>
#include <string.h>
#include <errno.h>
#include "memlib.h"
#include "config.h"
/* private variables */
static
char
*
mem_start_brk
;
/* points to first byte of heap */
static
char
*
mem_brk
;
/* points to last byte of heap */
static
char
*
mem_max_addr
;
/* largest legal heap address */
/*
* mem_init - initialize the memory system model
*/
void
mem_init
(
void
)
{
/* allocate the storage we will use to model the available VM */
if
((
mem_start_brk
=
(
char
*
)
malloc
(
MAX_HEAP
))
==
NULL
)
{
fprintf
(
stderr
,
"mem_init_vm: malloc error
\n
"
);
exit
(
1
);
}
mem_max_addr
=
mem_start_brk
+
MAX_HEAP
;
/* max legal heap address */
mem_brk
=
mem_start_brk
;
/* heap is empty initially */
}
/*
* mem_deinit - free the storage used by the memory system model
*/
void
mem_deinit
(
void
)
{
free
(
mem_start_brk
);
}
/*
* mem_reset_brk - reset the simulated brk pointer to make an empty heap
*/
void
mem_reset_brk
()
{
mem_brk
=
mem_start_brk
;
}
/*
* mem_sbrk - simple model of the sbrk function. Extends the heap
* by incr bytes and returns the start address of the new area. In
* this model, the heap cannot be shrunk.
*/
void
*
mem_sbrk
(
int
incr
)
{
char
*
old_brk
=
mem_brk
;
if
(
(
incr
<
0
)
||
((
mem_brk
+
incr
)
>
mem_max_addr
))
{
errno
=
ENOMEM
;
fprintf
(
stderr
,
"ERROR: mem_sbrk failed. Ran out of memory...
\n
"
);
return
(
void
*
)
-
1
;
}
mem_brk
+=
incr
;
return
(
void
*
)
old_brk
;
}
/*
* mem_heap_lo - return address of the first heap byte
*/
void
*
mem_heap_lo
()
{
return
(
void
*
)
mem_start_brk
;
}
/*
* mem_heap_hi - return address of last heap byte
*/
void
*
mem_heap_hi
()
{
return
(
void
*
)(
mem_brk
-
1
);
}
/*
* mem_heapsize() - returns the heap size in bytes
*/
size_t
mem_heapsize
()
{
return
(
size_t
)(
mem_brk
-
mem_start_brk
);
}
/*
* mem_pagesize() - returns the page size of the system
*/
size_t
mem_pagesize
()
{
return
(
size_t
)
getpagesize
();
}
assignment3/malloclab-handout/memlib.h
0 → 100644
View file @
01b4e45a
#include <unistd.h>
void
mem_init
(
void
);
void
mem_deinit
(
void
);
void
*
mem_sbrk
(
int
incr
);
void
mem_reset_brk
(
void
);
void
*
mem_heap_lo
(
void
);
void
*
mem_heap_hi
(
void
);
size_t
mem_heapsize
(
void
);
size_t
mem_pagesize
(
void
);
assignment3/malloclab-handout/mm.c
0 → 100644
View file @
01b4e45a
/*
* mm-naive.c - The fastest, least memory-efficient malloc package.
*
* In this naive approach, a block is allocated by simply incrementing
* the brk pointer. A block is pure payload. There are no headers or
* footers. Blocks are never coalesced or reused. Realloc is
* implemented directly using mm_malloc and mm_free.
*
* NOTE TO STUDENTS: Replace this header comment with your own header
* comment that gives a high level description of your solution.
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <string.h>
#include "mm.h"
#include "memlib.h"
/*********************************************************
* NOTE TO STUDENTS: Before you do anything else, please
* provide your team information in the following struct.
********************************************************/
team_t
team
=
{
/* Team name */
"TIGERS"
,
/* First member's full name */
"UMESH"
,
/* First member's email address */
"ub@cse.iitb.ac.in"
,
/* Second member's full name (leave blank if none) */
""
,
/* Second member's email address (leave blank if none) */
""
};
/* single word (4) or double word (8) alignment */
#define ALIGNMENT 8
/* rounds up to the nearest multiple of ALIGNMENT */
#define ALIGN(size) (((size) + (ALIGNMENT-1)) & ~0x7)
#define SIZE_T_SIZE (ALIGN(sizeof(size_t)))
/*
* mm_init - initialize the malloc package.
*/
int
mm_init
(
void
)
{
return
0
;
}
/*
* mm_malloc - Allocate a block by incrementing the brk pointer.
* Always allocate a block whose size is a multiple of the alignment.
*/
void
*
mm_malloc
(
size_t
size
)
{
int
newsize
=
ALIGN
(
size
+
SIZE_T_SIZE
);
void
*
p
=
mem_sbrk
(
newsize
);
if
(
p
==
(
void
*
)
-
1
)
return
NULL
;
else
{
*
(
size_t
*
)
p
=
size
;
return
(
void
*
)((
char
*
)
p
+
SIZE_T_SIZE
);
}
}
/*
* mm_free - Freeing a block does nothing.
*/
void
mm_free
(
void
*
ptr
)
{
}
/*
* mm_realloc - Implemented simply in terms of mm_malloc and mm_free
*/
void
*
mm_realloc
(
void
*
ptr
,
size_t
size
)
{
void
*
oldptr
=
ptr
;
void
*
newptr
;
size_t
copySize
;
newptr
=
mm_malloc
(
size
);
if
(
newptr
==
NULL
)
return
NULL
;
copySize
=
*
(
size_t
*
)((
char
*
)
oldptr
-
SIZE_T_SIZE
);
if
(
size
<
copySize
)
copySize
=
size
;
memcpy
(
newptr
,
oldptr
,
copySize
);
mm_free
(
oldptr
);
return
newptr
;
}
assignment3/malloclab-handout/mm.h
0 → 100644
View file @
01b4e45a
#include <stdio.h>
extern
int
mm_init
(
void
);
extern
void
*
mm_malloc
(
size_t
size
);
extern
void
mm_free
(
void
*
ptr
);
extern
void
*
mm_realloc
(
void
*
ptr
,
size_t
size
);
/*
* Students work in teams of one or two. Teams enter their team name,
* personal names and login IDs in a struct of this
* type in their bits.c file.
*/
typedef
struct
{
char
*
teamname
;
/* ID1+ID2 or ID1 */
char
*
name1
;
/* full name of first member */
char
*
id1
;
/* login ID of first member */
char
*
name2
;
/* full name of second member (if any) */
char
*
id2
;
/* login ID of second member */
}
team_t
;
extern
team_t
team
;
assignment3/malloclab-handout/short1-bal.rep
0 → 100644
View file @
01b4e45a
20000
6
12
1
a 0 2040
a 1 2040
f 1
a 2 48
a 3 4072
f 3
a 4 4072
f 0
f 2
a 5 4072
f 4
f 5
assignment3/malloclab-handout/short2-bal.rep
0 → 100644
View file @
01b4e45a
20000
6
12
1
a 0 2040
a 1 4010
a 2 48
a 3 4072
a 4 4072
a 5 4072
f 0
f 1
f 2
f 3
f 4
f 5
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment