Selaa lähdekoodia

initialize malloclab

homework4
邓博昊 9 kuukautta sitten
commit
63ad59c0ee
58 muutettua tiedostoa jossa 212223 lisäystä ja 0 poistoa
  1. +30
    -0
      Makefile
  2. +52
    -0
      README
  3. +279
    -0
      clock.c
  4. +22
    -0
      clock.h
  5. BIN
      clock.o
  6. +72
    -0
      config.h
  7. +251
    -0
      fcyc.c
  8. +68
    -0
      fcyc.h
  9. BIN
      fcyc.o
  10. +57
    -0
      fsecs.c
  11. +4
    -0
      fsecs.h
  12. BIN
      fsecs.o
  13. +106
    -0
      ftimer.c
  14. +14
    -0
      ftimer.h
  15. BIN
      ftimer.o
  16. +1017
    -0
      mdriver.c
  17. +101
    -0
      memlib.c
  18. +11
    -0
      memlib.h
  19. BIN
      memlib.o
  20. +110
    -0
      mm.c
  21. +23
    -0
      mm.h
  22. +16
    -0
      short1-bal.rep
  23. +16
    -0
      short2-bal.rep
  24. +42
    -0
      traces/Makefile
  25. +116
    -0
      traces/README
  26. +5698
    -0
      traces/amptjp-bal.rep
  27. +4809
    -0
      traces/amptjp.rep
  28. +12004
    -0
      traces/binary-bal.rep
  29. +8004
    -0
      traces/binary.rep
  30. +24004
    -0
      traces/binary2-bal.rep
  31. +16004
    -0
      traces/binary2.rep
  32. +5852
    -0
      traces/cccp-bal.rep
  33. +5036
    -0
      traces/cccp.rep
  34. +155
    -0
      traces/checktrace.pl
  35. +14404
    -0
      traces/coalescing-bal.rep
  36. +14404
    -0
      traces/coalescing.rep
  37. +6652
    -0
      traces/cp-decl-bal.rep
  38. +5687
    -0
      traces/cp-decl.rep
  39. +5384
    -0
      traces/expr-bal.rep
  40. +4541
    -0
      traces/expr.rep
  41. +39
    -0
      traces/gen_binary.pl
  42. +38
    -0
      traces/gen_binary2.pl
  43. +36
    -0
      traces/gen_coalescing.pl
  44. +62
    -0
      traces/gen_random.pl
  45. +57
    -0
      traces/gen_realloc.pl
  46. +46
    -0
      traces/gen_realloc2.pl
  47. +4804
    -0
      traces/random-bal.rep
  48. +4804
    -0
      traces/random.rep
  49. +4804
    -0
      traces/random2-bal.rep
  50. +4804
    -0
      traces/random2.rep
  51. +14405
    -0
      traces/realloc-bal.rep
  52. +14405
    -0
      traces/realloc.rep
  53. +14405
    -0
      traces/realloc2-bal.rep
  54. +14405
    -0
      traces/realloc2.rep
  55. +16
    -0
      traces/short1-bal.rep
  56. +16
    -0
      traces/short1.rep
  57. +16
    -0
      traces/short2-bal.rep
  58. +16
    -0
      traces/short2.rep

+ 30
- 0
Makefile Näytä tiedosto

@ -0,0 +1,30 @@
#
# Students' Makefile for the Malloc Lab
#
TEAM = bovik
VERSION = 1
HANDINDIR = /afs/cs.cmu.edu/academic/class/15213-f01/malloclab/handin
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
handin:
cp mm.c $(HANDINDIR)/$(TEAM)-$(VERSION)-mm.c
clean:
rm -f *~ *.o mdriver

+ 52
- 0
README Näytä tiedosto

@ -0,0 +1,52 @@
#####################################################################
# 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:
unix> mdriver -V -f short1-bal.rep
The -V option prints out helpful tracing and summary information.
To get a list of the driver flags:
unix> mdriver -h

+ 279
- 0
clock.c Näytä tiedosto

@ -0,0 +1,279 @@
/*
* 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;
}

+ 22
- 0
clock.h Näytä tiedosto

@ -0,0 +1,22 @@
/* 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();

BIN
clock.o Näytä tiedosto


+ 72
- 0
config.h Näytä tiedosto

@ -0,0 +1,72 @@
#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 "/home/aqua/桌面/malloclab"
/*
* 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 */

+ 251
- 0
fcyc.c Näytä tiedosto

@ -0,0 +1,251 @@
/*
* 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;
}

+ 68
- 0
fcyc.h Näytä tiedosto

@ -0,0 +1,68 @@
/*
* 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);

BIN
fcyc.o Näytä tiedosto


+ 57
- 0
fsecs.c Näytä tiedosto

@ -0,0 +1,57 @@
/****************************
* 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
}

+ 4
- 0
fsecs.h Näytä tiedosto

@ -0,0 +1,4 @@
typedef void (*fsecs_test_funct)(void *);
void init_fsecs(void);
double fsecs(fsecs_test_funct f, void *argp);

BIN
fsecs.o Näytä tiedosto


+ 106
- 0
ftimer.c Näytä tiedosto

@ -0,0 +1,106 @@
/*
* 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);
}

+ 14
- 0
ftimer.h Näytä tiedosto

@ -0,0 +1,14 @@
/*
* 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);

BIN
ftimer.o Näytä tiedosto


+ 1017
- 0
mdriver.c
File diff suppressed because it is too large
Näytä tiedosto


+ 101
- 0
memlib.c Näytä tiedosto

@ -0,0 +1,101 @@
/*
* 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();
}

+ 11
- 0
memlib.h Näytä tiedosto

@ -0,0 +1,11 @@
#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);

BIN
memlib.o Näytä tiedosto


+ 110
- 0
mm.c Näytä tiedosto

@ -0,0 +1,110 @@
/*
* 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 */
"ateam",
/* First member's full name */
"Harry Bovik",
/* First member's email address */
"bovik@cs.cmu.edu",
/* 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;
}

+ 23
- 0
mm.h Näytä tiedosto

@ -0,0 +1,23 @@
#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;

+ 16
- 0
short1-bal.rep Näytä tiedosto

@ -0,0 +1,16 @@
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

+ 16
- 0
short2-bal.rep Näytä tiedosto

@ -0,0 +1,16 @@
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

+ 42
- 0
traces/Makefile Näytä tiedosto

@ -0,0 +1,42 @@
all: synthetic-traces balanced-traces check-balance
synthetic-traces:
./gen_binary.pl
./gen_binary2.pl
./gen_coalescing.pl
./gen_random.pl
./gen_realloc.pl
./gen_realloc2.pl
balanced-traces:
./checktrace.pl < amptjp.rep > amptjp-bal.rep
./checktrace.pl < binary.rep > binary-bal.rep
./checktrace.pl < binary2.rep > binary2-bal.rep
./checktrace.pl < cccp.rep > cccp-bal.rep
./checktrace.pl < coalescing.rep > coalescing-bal.rep
./checktrace.pl < cp-decl.rep > cp-decl-bal.rep
./checktrace.pl < expr.rep > expr-bal.rep
./checktrace.pl < realloc.rep > realloc-bal.rep
./checktrace.pl < realloc2.rep > realloc2-bal.rep
./checktrace.pl < random.rep > random-bal.rep
./checktrace.pl < random2.rep > random2-bal.rep
./checktrace.pl < short1.rep > short1-bal.rep
./checktrace.pl < short2.rep > short2-bal.rep
check-balance:
./checktrace.pl -s < amptjp-bal.rep
./checktrace.pl -s < binary-bal.rep
./checktrace.pl -s < binary2-bal.rep
./checktrace.pl -s < cccp-bal.rep
./checktrace.pl -s < coalescing-bal.rep
./checktrace.pl -s < cp-decl-bal.rep
./checktrace.pl -s < expr-bal.rep
./checktrace.pl -s < realloc-bal.rep
./checktrace.pl -s < realloc2-bal.rep
./checktrace.pl -s < random-bal.rep
./checktrace.pl -s < random2-bal.rep
./checktrace.pl -s < short1-bal.rep
./checktrace.pl -s < short2-bal.rep
clean:
rm -f *~

+ 116
- 0
traces/README Näytä tiedosto

@ -0,0 +1,116 @@
#####################################################################
# CS:APP Malloc Lab
# Traces
#
# Copyright (c) 2002, R. Bryant and D. O'Hallaron, All rights reserved.
# May not be used, modified, or copied without permission.
#
######################################################################
This directory contains traces of allocate and free requests that are
used by the test harness to evaluate the student malloc packages.
*********
1. Files
*********
*.rep Original traces
*-bal.rep Balanced versions of the original traces
gen_XXX.pl Perl script that generates *.rep
checktrace.pl Checks trace for consistency and outputs a balanced version
Makefile Generates traces
Note: A "balanced" trace has a matching free request for each allocate
request.
**********************
2. Building the traces
**********************
To rebuild the traces from scratch, type
unix> make
********************
3. Trace file format
********************
A trace file is an ASCII file. It begins with a 4-line header:
<sugg_heapsize> /* suggested heap size (unused) */
<num_ids> /* number of request id's */
<num_ops> /* number of requests (operations) */
<weight> /* weight for this trace (unused) */
The header is followed by num_ops text lines. Each line denotes either
an allocate [a], reallocate [r], or free [f] request. The <alloc_id>
is an integer that uniquely identifies an allocate or reallocate
request.
a <id> <bytes> /* ptr_<id> = malloc(<bytes>) */
r <id> <bytes> /* realloc(ptr_<id>, <bytes>) */
f <id> /* free(ptr_<id>) */
For example, the following trace file:
<beginning of file>
20000
3
8
1
a 0 512
a 1 128
r 0 640
a 2 128
f 1
r 0 768
f 0
f 2
<end of file>
is balanced. It has a recommended heap size of 20000 bytes (ignored),
three distinct request ids (0, 1, and 2), eight different requests
(one per line), and a weight of 1 (ignored).
************************
4. Description of traces
************************
* short{1,2}-bal.rep
Tiny synthetic tracefiles for debugging
* {amptjp,cccp,cp-decl,expr}-bal.rep
Traces generated from real programs.
* {binary,binary2}-bal.rep
The allocation pattern is to alternatively allocate a small-sized
chunk of memory and a large-sized chunk. The small-sized chunks
(either 16 or 64 ) are deliberately set to be power of 2 while the
large-size chunks (either 112 or 448) are not a power of 2. Defeats
buddy algorithms. However, a simple-minded algorithm might prevail in
this scenario because a first-fit scheme will be good enough.
* coalescing-bal.rep
Repeatedly allocate two equal-sized chunks (4095 in size) and release
them, and then immediately allocate and free a chunk twice as big
(8190). This tests if the students' algorithm ever really releases
memory and does coalescing. The size is chosen to give advantage to
tree-based or segrated fits algorithms where there is no header or
footer overhead.
* {random,random2}-bal.rep
Random allocate and free requesets that simply test the correctness
and robustness of the algorithm.
* {realloc,realloc2}-bal.rep
Reallocate previously allocated blocks interleaved by other allocation
request. The purpose is to test whether a certain amount of internal
fragments are allocated or not. Naive realloc implementations that
always realloc a brand new block will suffer.

+ 5698
- 0
traces/amptjp-bal.rep
File diff suppressed because it is too large
Näytä tiedosto


+ 4809
- 0
traces/amptjp.rep
File diff suppressed because it is too large
Näytä tiedosto


+ 12004
- 0
traces/binary-bal.rep
File diff suppressed because it is too large
Näytä tiedosto


+ 8004
- 0
traces/binary.rep
File diff suppressed because it is too large
Näytä tiedosto


+ 24004
- 0
traces/binary2-bal.rep
File diff suppressed because it is too large
Näytä tiedosto


+ 16004
- 0
traces/binary2.rep
File diff suppressed because it is too large
Näytä tiedosto


+ 5852
- 0
traces/cccp-bal.rep
File diff suppressed because it is too large
Näytä tiedosto


+ 5036
- 0
traces/cccp.rep
File diff suppressed because it is too large
Näytä tiedosto


+ 155
- 0
traces/checktrace.pl Näytä tiedosto

@ -0,0 +1,155 @@
#!/usr/bin/perl
#!/usr/local/bin/perl
use Getopt::Std;
#######################################################################
# checktrace - trace file consistency checker and balancer.
#
# Copyright (c) 2002, R. Bryant and D. O'Hallaron, All rights reserved.
# May not be used, modified, or copied without permission.
#
# This script reads a Malloc Lab trace file, checks it for consistency,
# and outputs a balanced version by appending any necessary free requests.
#
#######################################################################
$| = 1; # autoflush output on every print statement
#
# void usage(void) - print help message and terminate
#
sub usage
{
printf STDERR "$_[0]\n";
printf STDERR "Usage: $0 [-hs]\n";
printf STDERR "Options:\n";
printf STDERR " -h Print this message\n";
printf STDERR " -s Emit only a brief summary\n";
die "\n" ;
}
##############
# Main routine
##############
#
# Parse and check the command line arguments
#
getopts('hs');
if ($opt_h) {
usage("");
}
$summary = $opt_s;
#
# HASH keeps a running tally of outstanding alloc/realloc
# requests. When a free request is encountered, the corresponding
# hash entry is deleted. When we are finished reading the trace,
# what is left are the unmatched alloc/realloc requests.
#
%HASH = ();
# Read the trace header values
$heap_size = <STDIN>;
chomp($heap_size);
$num_blocks = <STDIN>;
chomp($num_blocks);
$old_num_ops = <STDIN>;
chomp($old_num_ops);
$weight = <STDIN>;
chomp($weight);
#
# Find any allocate requests that don't have a matching free requests
#
$linenum = 4;
$requestnum = 0;
while ($line = <STDIN>) {
chomp($line);
$linenum++;
($cmd, $id, $size) = split(" ", $line);
# ignore blank lines
if (!$cmd) {
next;
}
# save the line for output later
$lines[$requestnum++] = $line;
#ignore realloc requests, as long as they are preceeded by an alloc request
if ($cmd eq "r") {
if (!$HASH{$id}) {
die "$0: ERROR[$linenum]: realloc without previous alloc\n";
}
next;
}
if ($cmd eq "a" and $HASH{$id} eq "a") {
die "$0: ERROR[$linenum]: allocate with no intervening free.\n";
}
if ($cmd eq "a" and $HASH{$id} eq "f") {
die "$0: ERROR[$linenum]: reused ID $id.\n";
}
if ($cmd eq "f" and !exists($HASH{$id})) {
die "$0: ERROR[$linenum]: freeing unallocated block.\n";
next;
}
if ($cmd eq "f" and !$HASH{$id} eq "f") {
die "$0: ERROR[$linenum]: freeing already freed block.\n";
next;
}
if ($cmd eq "f") {
delete $HASH{$id};
}
else {
$HASH{$id} = $cmd;
}
}
#
# If called with -s argument , print a brief balance summary and exit
#
if ($summary) {
if (!%HASH) {
print "Balanced trace.\n";
}
else {
print "Unbalanced tree.\n";
}
exit;
}
#
# Output a balanced version of the trace
#
$new_ops = keys %HASH;
$new_num_ops = $old_num_ops + $new_ops;
print "$heap_size\n";
print "$num_blocks\n";
print "$new_num_ops\n";
print "$weight\n";
# print the old requests
foreach $item (@lines) {
print "$item\n";
}
# print a set of free requests that will balance the trace
foreach $key (sort keys %HASH) {
if ($HASH{$key} ne "a" and $HASH{$key} ne "r") {
die "$0: ERROR: Invalid free request in residue.\n";
}
print "f $key\n";
}
exit;

+ 14404
- 0
traces/coalescing-bal.rep
File diff suppressed because it is too large
Näytä tiedosto


+ 14404
- 0
traces/coalescing.rep
File diff suppressed because it is too large
Näytä tiedosto


+ 6652
- 0
traces/cp-decl-bal.rep
File diff suppressed because it is too large
Näytä tiedosto


+ 5687
- 0
traces/cp-decl.rep
File diff suppressed because it is too large
Näytä tiedosto


+ 5384
- 0
traces/expr-bal.rep
File diff suppressed because it is too large
Näytä tiedosto


+ 4541
- 0
traces/expr.rep
File diff suppressed because it is too large
Näytä tiedosto


+ 39
- 0
traces/gen_binary.pl Näytä tiedosto

@ -0,0 +1,39 @@
#!/usr/bin/perl
#!/usr/local/bin/perl
$out_filename = "binary.rep";
$blk_size1 = 64;
$blk_size2 = 512 - $blk_size1;
$num_iters = 2000;
# Open output file
open OUTFILE, ">$out_filename" or die "Cannot create $out_filename\n";
# Calculate misc parameters
$blk_size12 = $blk_size1 + $blk_size2;
$suggested_heap_size = ($blk_size1 + $blk_size2 + $blk_size12)*$num_iters + 100;
$num_blocks = 3*$num_iters;
$num_ops = 4*$num_iters;
print OUTFILE "$suggested_heap_size\n";
print OUTFILE "$num_blocks\n";
print OUTFILE "$num_ops\n";
print OUTFILE "1\n";
for ($i = 0; $i < $num_iters; $i += 1) {
$seq1 = 2*$i;
$seq2 = 2*$i + 1;
print OUTFILE "a $seq1 $blk_size1\n";
print OUTFILE "a $seq2 $blk_size2\n";
}
for ($i = 0; $i < $num_iters; $i += 1) {
$fseq = 2*$i + 1;
print OUTFILE "f $fseq\n";
}
for ($i = 0; $i < $num_iters; $i += 1) {
$aseq = 2*$num_iters + $i;
print OUTFILE "a $aseq $blk_size12\n";
}
close OUTFILE;

+ 38
- 0
traces/gen_binary2.pl Näytä tiedosto

@ -0,0 +1,38 @@
#!/usr/bin/perl
$out_filename = "binary2.rep";
$blk_size1 = 16;
$blk_size2 = 128 - $blk_size1;
$num_iters = 4000;
# Open output file
open OUTFILE, ">$out_filename" or die "Cannot create $out_filename\n";
# Calculate misc parameters
$blk_size12 = $blk_size1 + $blk_size2;
$suggested_heap_size = ($blk_size1 + $blk_size2 + $blk_size12)*$num_iters + 100;
$num_blocks = 3*$num_iters;
$num_ops = 4*$num_iters;
print OUTFILE "$suggested_heap_size\n";
print OUTFILE "$num_blocks\n";
print OUTFILE "$num_ops\n";
print OUTFILE "1\n";
for ($i = 0; $i < $num_iters; $i += 1) {
$seq1 = 2*$i;
$seq2 = 2*$i + 1;
print OUTFILE "a $seq1 $blk_size1\n";
print OUTFILE "a $seq2 $blk_size2\n";
}
for ($i = 0; $i < $num_iters; $i += 1) {
$fseq = 2*$i + 1;
print OUTFILE "f $fseq\n";
}
for ($i = 0; $i < $num_iters; $i += 1) {
$aseq = 2*$num_iters + $i;
print OUTFILE "a $aseq $blk_size12\n";
}
close OUTFILE;

+ 36
- 0
traces/gen_coalescing.pl Näytä tiedosto

@ -0,0 +1,36 @@
#!/usr/bin/perl
#!/usr/local/bin/perl
$out_filename = "coalescing.rep";
$blk_size = 4095;
$num_iters = 2400;
# Open output file
open OUTFILE, ">$out_filename" or die "Cannot create $out_filename\n";
# Calculate misc parameters
$blk_size2 = 2*$blk_size;
$suggested_heap_size = 2*$blk_size*$num_iters + 100;
$num_blocks = 3*$num_iters;
$num_ops = 6*$num_iters;
print OUTFILE "$suggested_heap_size\n";
print OUTFILE "$num_blocks\n";
print OUTFILE "$num_ops\n";
print OUTFILE "1\n";
for ($i = 0; $i < $num_iters; $i += 1) {
$blk1 = 3*$i;
$blk2 = $blk1 + 1;
$blk3 = $blk1 + 2;
print OUTFILE "a $blk1 $blk_size\n";
print OUTFILE "a $blk2 $blk_size\n";
print OUTFILE "f $blk1\n";
print OUTFILE "f $blk2\n";
print OUTFILE "a $blk3 $blk_size2\n";
print OUTFILE "f $blk3\n";
}
close OUTFILE;

+ 62
- 0
traces/gen_random.pl Näytä tiedosto

@ -0,0 +1,62 @@
#!/usr/bin/perl
#!/usr/local/bin/perl
$out_filename = $argv[0];
$out_filename = "random.rep" unless $out_filename;
$num_blocks = $argv[1];
# $num_blocks = 1200 unless $num_blocks;
$num_blocks = 2400 unless $num_blocks;
$max_blk_size = $argv[2];
$max_blk_size = 32768 unless $max_blk_size;
#print "Output file: $out_filename\n";
#print "Number of blocks: $num_blocks\n";
#print "Max block size: $max_blk_size\n";
# Create trace
# Make a series of malloc()s
for ($i = 0; $i < $num_blocks; $i += 1) {
$size = int(rand $max_blk_size);
$op = {};
$op->{type} = "a";
$op->{seq} = $i;
$op->{size} = $size;
$total_block_size += $size;
push @trace, $op;
}
# Insert free()s in proper places
for ($i = 0; $i < $num_blocks; $i += 1) {
for ($minval = $i; $minval < $num_blocks + $i; $minval += 1) {
if (($trace[$minval]->{type} eq "a") && ($trace[$minval]->{seq} == $i)) {
last;
}
}
$pos = int(rand($num_blocks + $i - $minval - 1) + $minval + 1);
$op = {};
$op->{type} = "f";
$op->{seq} = $i;
splice @trace, $pos, 0, $op;
}
# Open output file
open OUTFILE, ">$out_filename" or die "Cannot create $out_filename\n";
# Calculate misc parameters
$suggested_heap_size = $total_block_size + 100;
$num_ops = 2*$num_blocks;
print OUTFILE "$suggested_heap_size\n";
print OUTFILE "$num_blocks\n";
print OUTFILE "$num_ops\n";
print OUTFILE "1\n";
for ($i = 0; $i < 2*$num_blocks; $i += 1) {
if ($trace[$i]->{type} eq "a") {
print OUTFILE "$trace[$i]->{type} $trace[$i]->{seq} $trace[$i]->{size}\n";
} else {
print OUTFILE "$trace[$i]->{type} $trace[$i]->{seq}\n";
}
}
close OUTFILE;

+ 57
- 0
traces/gen_realloc.pl Näytä tiedosto

@ -0,0 +1,57 @@
#!/usr/bin/perl
#!/usr/local/bin/perl
$out_filename = "realloc.rep";
$realloc_size = 512;
$size_increment = 128;
$malloc_size = 128;
$num_iters = 4800;
# Open output file
open OUTFILE, ">$out_filename" or die "Cannot create $out_filename\n";
# Calculate misc parameters
$suggested_heap_size = num_iters* ($realloc_size+$size_increment*2 )+100;
$num_blocks = $num_iters+1;
$num_ops = ($num_iters )*3 +1;
$blk = 1;
print OUTFILE "$suggested_heap_size\n";
print OUTFILE "$num_blocks\n";
print OUTFILE "$num_ops\n";
print OUTFILE "1\n";
print OUTFILE "a 0 $realloc_size\n";
print OUTFILE "a $blk $malloc_size\n";
for ($i = 1; $i < $num_iters; $i += 1) {
$blk += 1;
$realloc_size += $size_increment;
print OUTFILE "r 0 $realloc_size\n";
print OUTFILE "a $blk $malloc_size\n";
$prevblk = $blk-1;
print OUTFILE "f $prevblk\n";
}
$finalblk = $blk;
print OUTFILE "f $finalblk\n";
print OUTFILE "f 0";
print OUTFILE
close OUTFILE;

+ 46
- 0
traces/gen_realloc2.pl Näytä tiedosto

@ -0,0 +1,46 @@
#!/usr/bin/perl
#!/usr/local/bin/perl
$out_filename = "realloc2.rep";
$realloc_size = 4092;
$size_increment = 5;
$malloc_size = 16;
$num_iters = 4800;
# Open output file
open OUTFILE, ">$out_filename" or die "Cannot create $out_filename\n";
# Calculate misc parameters
$suggested_heap_size = $realloc_size+$size_increment*($num_iters-1)+$malloc_size*$num_iters+100;
$num_blocks = $num_iters + 1;
$num_ops = 3 * $num_iters + 1;
$blk = 1;
print OUTFILE "$suggested_heap_size\n";
print OUTFILE "$num_blocks\n";
print OUTFILE "$num_ops\n";
print OUTFILE "1\n";
print OUTFILE "a 0 $realloc_size\n";
print OUTFILE "a $blk $malloc_size\n";
for ($i = 1; $i < $num_iters; $i += 1) {
$blk += 1;
$realloc_size += $size_increment;
print OUTFILE "r 0 $realloc_size\n";
print OUTFILE "a $blk $malloc_size\n";
$prevblk = $blk-1;
print OUTFILE "f $prevblk\n";
}
$finalblk = $blk;
print OUTFILE "f $finalblk\n";
print OUTFILE "f 0";
print OUTFILE
close OUTFILE;

+ 4804
- 0
traces/random-bal.rep
File diff suppressed because it is too large
Näytä tiedosto


+ 4804
- 0
traces/random.rep
File diff suppressed because it is too large
Näytä tiedosto


+ 4804
- 0
traces/random2-bal.rep
File diff suppressed because it is too large
Näytä tiedosto


+ 4804
- 0
traces/random2.rep
File diff suppressed because it is too large
Näytä tiedosto


+ 14405
- 0
traces/realloc-bal.rep
File diff suppressed because it is too large
Näytä tiedosto


+ 14405
- 0
traces/realloc.rep
File diff suppressed because it is too large
Näytä tiedosto


+ 14405
- 0
traces/realloc2-bal.rep
File diff suppressed because it is too large
Näytä tiedosto


+ 14405
- 0
traces/realloc2.rep
File diff suppressed because it is too large
Näytä tiedosto


+ 16
- 0
traces/short1-bal.rep Näytä tiedosto

@ -0,0 +1,16 @@
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

+ 16
- 0
traces/short1.rep Näytä tiedosto

@ -0,0 +1,16 @@
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

+ 16
- 0
traces/short2-bal.rep Näytä tiedosto

@ -0,0 +1,16 @@
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

+ 16
- 0
traces/short2.rep Näytä tiedosto

@ -0,0 +1,16 @@
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

Ladataan…
Peruuta
Tallenna