《CSAPP》(第3版)答案(第九章)

《CSAPP》(第3版)答案(第九章)

P11

  • A
      13 12 11 10  9  8  7  6  5  4  3  2  1  0
     +--|--|--|--|--|--|--|--|--|--|--|--|--|--+
     | 0| 0| 0| 0| 1| 0| 0| 1| 1| 1| 1| 1| 0| 0|
     +--|--|--|--|--|--|--|--|--|--|--|--|--|--+
  • B
param value
VPN 0x09
TLBI 0x01
TLBT 0x02
hit? No
page falut? No
PPN 0x17
  • C
      11 10  9  8  7  6  5  4  3  2  1  0
     +--|--|--|--|--|--|--|--|--|--|--|--+
     | 0| 1| 0| 1| 1| 1| 1| 1| 1| 1| 0| 0|
     +--|--|--|--|--|--|--|--|--|--|--|--+
  • D
param value
CO 0x00
CI 0x0F
CT 0x17
hit? No
value -----

P12

  • A
      13 12 11 10  9  8  7  6  5  4  3  2  1  0
     +--|--|--|--|--|--|--|--|--|--|--|--|--|--+
     | 0| 0| 0| 0| 1| 1| 1| 0| 1| 0| 1| 0| 0| 1|
     +--|--|--|--|--|--|--|--|--|--|--|--|--|--+
  • B
param value
VPN 0x0E
TLBI 0x02
TLBT 0x03
hit? No
page falut? No
PPN 0x11
  • C
      11 10  9  8  7  6  5  4  3  2  1  0
     +--|--|--|--|--|--|--|--|--|--|--|--+
     | 0| 1| 0| 0| 0| 1| 1| 0| 1| 0| 0| 1|
     +--|--|--|--|--|--|--|--|--|--|--|--+
  • D
param value
CO 0x01
CI 0x0A
CT 0x11
hit? No
value -----

P13

  • A
      13 12 11 10  9  8  7  6  5  4  3  2  1  0
     +--|--|--|--|--|--|--|--|--|--|--|--|--|--+
     | 0| 0| 0| 0| 0| 0| 0| 1| 0| 0| 0| 0| 0| 0|
     +--|--|--|--|--|--|--|--|--|--|--|--|--|--+
  • B
param value
VPN 0x01
TLBI 0x01
TLBT 0x00
hit? No
page falut? Yes

P14

#include <stdio.h>
#include <assert.h>
#include "csapp.h"

void test(char* filename, char* content) {
  int fd;
  char buf[20];
  fd = Open(filename, O_RDONLY, 0);
  Read(fd, buf, strlen(content));
  assert( !strncmp(buf, content, strlen(content)) );
}

int touch(char* filename, char* content) {
  int fd;
  umask(DEF_UMASK);
  fd = Open(filename, O_WRONLY|O_CREAT|O_TRUNC, DEF_MODE);
  Write(fd, content, strlen(content));
  Close(fd);
}

int main(int argc, char* argv[]) {
  touch("hello.txt", "Hello, world!");
  test("hello.txt", "Hello, world!");
  struct stat stat;
  int fd;
  char* bufp;
  size_t size;
  fd = Open("hello.txt", O_RDWR, 0);
  fstat(fd, &stat);
  size = stat.st_size;
  bufp = Mmap(NULL, size, PROT_WRITE, MAP_SHARED, fd, 0);
  *bufp = 'J';
  Munmap(bufp, size);
  
  test("hello.txt", "Jello, world!");
  return 0;
}

P15

malloc size header
malloc(3) 8 0x9
malloc(11) 16 0x11
malloc(20) 24 0x19
malloc(21) 24 0x19

P16

alignment allocated block spare block min block size
word Header & Footer Header & Footer 16
word Header Header & Footer 16
double word Header & Footer Header & Footer 16
double word Header Header & Footer 16

P17

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mm.h"
#include "memlib.h"
/* $begin mallocmacros */
/* Basic constants and macros */
#define WSIZE       4       /* Word and header/footer size (bytes) */ //line:vm:mm:beginconst
#define DSIZE       8       /* Double word size (bytes) */
#define CHUNKSIZE  (1<<12)  /* Extend heap by this amount (bytes) */  //line:vm:mm:endconst
#define MAX(x, y) ((x) > (y)? (x) : (y))
/* Pack a size and allocated bit into a word */
#define PACK(size, alloc)  ((size) | (alloc)) //line:vm:mm:pack
/* Read and write a word at address p */
#define GET(p)       (*(unsigned int *)(p))            //line:vm:mm:get
#define PUT(p, val)  (*(unsigned int *)(p) = (val))    //line:vm:mm:put
/* Read the size and allocated fields from address p */
#define GET_SIZE(p)  (GET(p) & ~0x7)                   //line:vm:mm:getsize
#define GET_ALLOC(p) (GET(p) & 0x1)                    //line:vm:mm:getalloc
/* Given block ptr bp, compute address of its header and footer */
#define HDRP(bp)       ((char *)(bp) - WSIZE)                      //line:vm:mm:hdrp
#define FTRP(bp)       ((char *)(bp) + GET_SIZE(HDRP(bp)) - DSIZE) //line:vm:mm:ftrp
/* Given block ptr bp, compute address of next and previous blocks */
#define NEXT_BLKP(bp)  ((char *)(bp) + GET_SIZE(((char *)(bp) - WSIZE))) //line:vm:mm:nextblkp
#define PREV_BLKP(bp)  ((char *)(bp) - GET_SIZE(((char *)(bp) - DSIZE))) //line:vm:mm:prevblkp
/* $end mallocmacros */
/* Global variables */
static char *heap_listp = 0;  /* Pointer to first block */
static char *rover;           /* Next fit rover */
/* Function prototypes for internal helper routines */
static void *extend_heap(size_t words);
static void place(void *bp, size_t asize);
static void *find_fit(size_t asize);
static void *coalesce(void *bp);
static void printblock(void *bp);
static void checkheap(int verbose);
static void checkblock(void *bp);
/*
 * mm_init - Initialize the memory manager
 */
/* $begin mminit */
int mm_init(void)
{
  mem_init();
  /* Create the initial empty heap */
  if ((heap_listp = mem_sbrk(4*WSIZE)) == (void *)-1) //line:vm:mm:begininit
    return -1;
  PUT(heap_listp, 0);                          /* Alignment padding */
  PUT(heap_listp + (1*WSIZE), PACK(DSIZE, 1)); /* Prologue header */
  PUT(heap_listp + (2*WSIZE), PACK(DSIZE, 1)); /* Prologue footer */
  PUT(heap_listp + (3*WSIZE), PACK(0, 1));     /* Epilogue header */
  heap_listp += (2*WSIZE);                     //line:vm:mm:endinit
  /* $end mminit */
  rover = heap_listp;
  /* $begin mminit *
  /* Extend the empty heap with a free block of CHUNKSIZE bytes */
  if (extend_heap(CHUNKSIZE/WSIZE) == NULL)
    return -1;
  return 0;
}
/* $end mminit */
/*
 * mm_malloc - Allocate a block with at least size bytes of payload
 */
/* $begin mmmalloc */
void *mm_malloc(size_t size)
{
  size_t asize;      /* Adjusted block size */
  size_t extendsize; /* Amount to extend heap if no fit */
  char *bp;
  /* $end mmmalloc */
  if (heap_listp == 0){
    mm_init();
  }
  /* $begin mmmalloc */
  /* Ignore spurious requests */
  if (size == 0)
    return NULL;
  /* Adjust block size to include overhead and alignment reqs. */
  if (size <= DSIZE)                                          //line:vm:mm:sizeadjust1
    asize = 2*DSIZE;                                        //line:vm:mm:sizeadjust2
  else
    asize = DSIZE * ((size + (DSIZE) + (DSIZE-1)) / DSIZE); //line:vm:mm:sizeadjust3
  /* Search the free list for a fit */
  if ((bp = find_fit(asize)) != NULL) {  //line:vm:mm:findfitcall
    place(bp, asize);                  //line:vm:mm:findfitplace
    return bp;
  }
  /* No fit found. Get more memory and place the block */
  extendsize = MAX(asize,CHUNKSIZE);                 //line:vm:mm:growheap1
  if ((bp = extend_heap(extendsize/WSIZE)) == NULL)
    return NULL;                                  //line:vm:mm:growheap2
  place(bp, asize);                                 //line:vm:mm:growheap3
  return bp;
}
/* $end mmmalloc */
/*
 * mm_free - Free a block
 */
/* $begin mmfree */
void mm_free(void *bp)
{
  /* $end mmfree */
  if (bp == 0)
    return;
  /* $begin mmfree */
  size_t size = GET_SIZE(HDRP(bp));
  /* $end mmfree */
  if (heap_listp == 0){
    mm_init();
  }
  /* $begin mmfree */
  PUT(HDRP(bp), PACK(size, 0));
  PUT(FTRP(bp), PACK(size, 0));
  coalesce(bp);
}
/* $end mmfree */
/*
 * coalesce - Boundary tag coalescing. Return ptr to coalesced block
 */
/* $begin mmfree */
static void *coalesce(void *bp)
{
  size_t prev_alloc = GET_ALLOC(FTRP(PREV_BLKP(bp)));
  size_t next_alloc = GET_ALLOC(HDRP(NEXT_BLKP(bp)));
  size_t size = GET_SIZE(HDRP(bp));
  if (prev_alloc && next_alloc) {            /* Case 1 */
    return bp;
  }
  else if (prev_alloc && !next_alloc) {      /* Case 2 */
    size += GET_SIZE(HDRP(NEXT_BLKP(bp)));
    PUT(HDRP(bp), PACK(size, 0));
    PUT(FTRP(bp), PACK(size,0));
  }
  else if (!prev_alloc && next_alloc) {      /* Case 3 */
    size += GET_SIZE(HDRP(PREV_BLKP(bp)));
    PUT(FTRP(bp), PACK(size, 0));
    PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0));
    bp = PREV_BLKP(bp);
  }
  else {                                     /* Case 4 */
    size += GET_SIZE(HDRP(PREV_BLKP(bp))) +
      GET_SIZE(FTRP(NEXT_BLKP(bp)));
    PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0));
    PUT(FTRP(NEXT_BLKP(bp)), PACK(size, 0));
    bp = PREV_BLKP(bp);
  }
  /* $end mmfree */
  /* Make sure the rover isn't pointing into the free block */
  /* that we just coalesced */
  if ((rover > (char *)bp) && (rover < NEXT_BLKP(bp)))
    rover = bp;
  /* $begin mmfree */
  return bp;
}
/* $end mmfree */
/*
 * mm_realloc - Naive implementation of realloc
 */
void *mm_realloc(void *ptr, size_t size)
{
  size_t oldsize;
  void *newptr;
  /* If size == 0 then this is just free, and we return NULL. */
  if(size == 0) {
    mm_free(ptr);
    return 0;
  }
  /* If oldptr is NULL, then this is just malloc. */
  if(ptr == NULL) {
    return mm_malloc(size);
  }
  newptr = mm_malloc(size);
  /* If realloc() fails the original block is left untouched  */
  if(!newptr) {
    return 0;
  }
  /* Copy the old data. */
  oldsize = GET_SIZE(HDRP(ptr));
  if(size < oldsize) oldsize = size;
  memcpy(newptr, ptr, oldsize);
  /* Free the old block. */
  mm_free(ptr);
  return newptr;
}
/*
 * mm_checkheap - Check the heap for correctness
 */
void mm_checkheap(int verbose)
{
  checkheap(verbose);
}
/*
 * The remaining routines are internal helper routines
 */
/*
 * extend_heap - Extend heap with free block and return its block pointer
 */
/* $begin mmextendheap */
static void *extend_heap(size_t words)
{
  char *bp;
  size_t size;
  /* Allocate an even number of words to maintain alignment */
  size = (words % 2) ? (words+1) * WSIZE : words * WSIZE; //line:vm:mm:beginextend
  if ((long)(bp = mem_sbrk(size)) == -1)
    return NULL;                                        //line:vm:mm:endextend
  /* Initialize free block header/footer and the epilogue header */
  PUT(HDRP(bp), PACK(size, 0));         /* Free block header */   //line:vm:mm:freeblockhdr
  PUT(FTRP(bp), PACK(size, 0));         /* Free block footer */   //line:vm:mm:freeblockftr
  PUT(HDRP(NEXT_BLKP(bp)), PACK(0, 1)); /* New epilogue header */ //line:vm:mm:newepihdr
  /* Coalesce if the previous block was free */
  return coalesce(bp);                                          //line:vm:mm:returnblock
}
/* $end mmextendheap */
/*
 * place - Place block of asize bytes at start of free block bp
 *         and split if remainder would be at least minimum block size
 */
/* $begin mmplace */
/* $begin mmplace-proto */
static void place(void *bp, size_t asize)
  /* $end mmplace-proto */
{
  size_t csize = GET_SIZE(HDRP(bp));
  if ((csize - asize) >= (2*DSIZE)) {
    PUT(HDRP(bp), PACK(asize, 1));
    PUT(FTRP(bp), PACK(asize, 1));
    bp = NEXT_BLKP(bp);
    PUT(HDRP(bp), PACK(csize-asize, 0));
    PUT(FTRP(bp), PACK(csize-asize, 0));
  }
  else {
    PUT(HDRP(bp), PACK(csize, 1));
    PUT(FTRP(bp), PACK(csize, 1));
  }
}
/* $end mmplace */
/*
 * find_fit - Find a fit for a block with asize bytes
 */
/* $begin mmfirstfit */
/* $begin mmfirstfit-proto */
static void *find_fit(size_t asize)
  /* $end mmfirstfit-proto */
{
  /* $end mmfirstfit */
  /* Next fit search */
  char *oldrover = rover;
  /* Search from the rover to the end of list */
  for ( ; GET_SIZE(HDRP(rover)) > 0; rover = NEXT_BLKP(rover))
    if (!GET_ALLOC(HDRP(rover)) && (asize <= GET_SIZE(HDRP(rover))))
      return rover;
  /* search from start of list to old rover */
  for (rover = heap_listp; rover < oldrover; rover = NEXT_BLKP(rover))
    if (!GET_ALLOC(HDRP(rover)) && (asize <= GET_SIZE(HDRP(rover))))
      return rover;
  return NULL;  /* no fit found */
}
/* $end mmfirstfit */
static void printblock(void *bp)
{
  size_t hsize, halloc, fsize, falloc;
  checkheap(0);
  hsize = GET_SIZE(HDRP(bp));
  halloc = GET_ALLOC(HDRP(bp));
  fsize = GET_SIZE(FTRP(bp));
  falloc = GET_ALLOC(FTRP(bp));
  if (hsize == 0) {
    printf("%p: EOL\n", bp);
    return;
  }
  printf("%p: header: [%ld:%c] footer: [%ld:%c]\n", bp,
      hsize, (halloc ? 'a' : 'f'),
      fsize, (falloc ? 'a' : 'f'));
}
static void checkblock(void *bp)
{
  if ((size_t)bp % 8)
    printf("Error: %p is not doubleword aligned\n", bp);
  if (GET(HDRP(bp)) != GET(FTRP(bp)))
    printf("Error: header does not match footer\n");
}
/*
 * checkheap - Minimal check of the heap for consistency
 */
void checkheap(int verbose)
{
  char *bp = heap_listp;
  if (verbose)
    printf("Heap (%p):\n", heap_listp);
  if ((GET_SIZE(HDRP(heap_listp)) != DSIZE) || !GET_ALLOC(HDRP(heap_listp)))
    printf("Bad prologue header\n");
  checkblock(heap_listp);
  for (bp = heap_listp; GET_SIZE(HDRP(bp)) > 0; bp = NEXT_BLKP(bp)) {
    if (verbose)
      printblock(bp);
    checkblock(bp);
  }
  if (verbose)
    printblock(bp);
  if ((GET_SIZE(HDRP(bp)) != 0) || !(GET_ALLOC(HDRP(bp))))
    printf("Bad epilogue header\n");
}

P18

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mm.h"
#include "memlib.h"
/* $begin mallocmacros */
/* Basic constants and macros */
#define WSIZE       4       /* Word and header/footer size (bytes) */ //line:vm:mm:beginconst
#define DSIZE       8       /* Double word size (bytes) */
#define CHUNKSIZE  (1<<12)  /* Extend heap by this amount (bytes) */  //line:vm:mm:endconst
#define MAX(x, y) ((x) > (y)? (x) : (y))
/* Pack a size and allocated bit into a word */
#define PACK(size, alloc, prev_alloc)  ((size) | (alloc) | (prev_alloc << 1)) //line:vm:mm:pack
/* Read and write a word at address p */
#define GET(p)       (*(unsigned int *)(p))            //line:vm:mm:get
#define PUT(p, val)  (*(unsigned int *)(p) = (val))    //line:vm:mm:put
/* Read the size and allocated fields from address p */
#define GET_SIZE(p)  (GET(p) & ~0x7)                   //line:vm:mm:getsize
#define GET_ALLOC(p) (GET(p) & 0x1)                    //line:vm:mm:getalloc
#define GET_PREV_ALLOC(p) ((GET(p) >> 1) & 0x1)
/* Given block ptr bp, compute address of its header and footer */
#define HDRP(bp)       ((char *)(bp) - WSIZE)                      //line:vm:mm:hdrp
#define FTRP(bp)       ((char *)(bp) + GET_SIZE(HDRP(bp)) - DSIZE) //line:vm:mm:ftrp
/* Given block ptr bp, compute address of next and previous blocks */
#define NEXT_BLKP(bp)  ((char *)(bp) + GET_SIZE(((char *)(bp) - WSIZE))) //line:vm:mm:nextblkp
#define PREV_BLKP(bp)  ((char *)(bp) - GET_SIZE(((char *)(bp) - DSIZE))) //line:vm:mm:prevblkp
/* $end mallocmacros */
/* Global variables */
static char *heap_listp = 0;  /* Pointer to first block */
/* Function prototypes for internal helper routines */
static void *extend_heap(size_t words);
static void place(void *bp, size_t asize);
static void *find_fit(size_t asize);
static void *coalesce(void *bp);
static void printblock(void *bp);
static void checkheap(int verbose);
static void checkblock(void *bp);
/*
 * mm_init - Initialize the memory manager
 */
/* $begin mminit */
int mm_init(void)
{
  mem_init();
  /* Create the initial empty heap */
  if ((heap_listp = mem_sbrk(4*WSIZE)) == (void *)-1) //line:vm:mm:begininit
    return -1;
  PUT(heap_listp, 0);                          /* Alignment padding */
  PUT(heap_listp + (1*WSIZE), PACK(DSIZE, 1, 1)); /* Prologue header */
  PUT(heap_listp + (2*WSIZE), PACK(DSIZE, 1, 1)); /* Prologue footer */
  PUT(heap_listp + (3*WSIZE), PACK(0, 1, 1));     /* Epilogue header */
  heap_listp += (2*WSIZE);                     //line:vm:mm:endinit
  /* $end mminit */
  /* $begin mminit */
  /* Extend the empty heap with a free block of CHUNKSIZE bytes */
  if (extend_heap(CHUNKSIZE/WSIZE) == NULL)
    return -1;
  return 0;
}
/* $end mminit */
/*
 * mm_malloc - Allocate a block with at least size bytes of payload
 */
/* $begin mmmalloc */
void *mm_malloc(size_t size)
{
  size_t asize;      /* Adjusted block size */
  size_t extendsize; /* Amount to extend heap if no fit */
  char *bp;
  /* $end mmmalloc */
  if (heap_listp == 0){
    mm_init();
  }
  /* $begin mmmalloc */
  /* Ignore spurious requests */
  if (size == 0)
    return NULL;
  /* Adjust block size to include overhead and alignment reqs. */
  if (size <= WSIZE)
    asize = DSIZE;
  else
    asize = DSIZE * ((size + (WSIZE) + (DSIZE-1)) / DSIZE); //line:vm:mm:sizeadjust3
  /* Search the free list for a fit */
  if ((bp = find_fit(asize)) != NULL) {  //line:vm:mm:findfitcall
    place(bp, asize);                  //line:vm:mm:findfitplace
    return bp;
  }
  /* No fit found. Get more memory and place the block */
  extendsize = MAX(asize,CHUNKSIZE);                 //line:vm:mm:growheap1
  if ((bp = extend_heap(extendsize/WSIZE)) == NULL)
    return NULL;                                  //line:vm:mm:growheap2
  place(bp, asize);                                 //line:vm:mm:growheap3
  return bp;
}
/* $end mmmalloc */
/*
 * mm_free - Free a block
 */
/* $begin mmfree */
void mm_free(void *bp)
{
  /* $end mmfree */
  if (bp == 0)
    return;
  /* $begin mmfree */
  size_t size = GET_SIZE(HDRP(bp));
  /* $end mmfree */
  if (heap_listp == 0){
    mm_init();
  }
  /* $begin mmfree */
  PUT(HDRP(bp), PACK(size, 0, GET_PREV_ALLOC(HDRP(bp))));
  PUT(FTRP(bp), PACK(size, 0, GET_PREV_ALLOC(HDRP(bp))));
  if (GET_ALLOC(HDRP(NEXT_BLKP(bp))))
    PUT(HDRP(NEXT_BLKP(bp)), PACK(GET_SIZE(HDRP(NEXT_BLKP(bp))), 1, 0));
  else {
    PUT(HDRP(NEXT_BLKP(bp)), PACK(GET_SIZE(HDRP(NEXT_BLKP(bp))), 0, 0));
    PUT(FTRP(NEXT_BLKP(bp)), PACK(GET_SIZE(HDRP(NEXT_BLKP(bp))), 0, 0));
  }
  coalesce(bp);
}
/* $end mmfree */
/*
 * coalesce - Boundary tag coalescing. Return ptr to coalesced block
 */
/* $begin mmfree */
static void *coalesce(void *bp)
{
  size_t prev_alloc = GET_PREV_ALLOC(HDRP(bp));
  size_t next_alloc = GET_ALLOC(HDRP(NEXT_BLKP(bp)));
  size_t size = GET_SIZE(HDRP(bp));
  if (prev_alloc && next_alloc) {            /* Case 1 */
    return bp;
  }
  else if (prev_alloc && !next_alloc) {      /* Case 2 */
    size += GET_SIZE(HDRP(NEXT_BLKP(bp)));
    PUT(HDRP(bp), PACK(size, 0, 1));
    PUT(FTRP(bp), PACK(size, 0, 1));
  }
  else if (!prev_alloc && next_alloc) {      /* Case 3 */
    size += GET_SIZE(HDRP(PREV_BLKP(bp)));
    PUT(FTRP(bp), PACK(size, 0, 1));
    PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0, 1));
    bp = PREV_BLKP(bp);
  }
  else {                                     /* Case 4 */
    size += GET_SIZE(HDRP(PREV_BLKP(bp))) +
      GET_SIZE(FTRP(NEXT_BLKP(bp)));
    PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0, 1));
    PUT(FTRP(NEXT_BLKP(bp)), PACK(size, 0, 1));
    bp = PREV_BLKP(bp);
  }
  /* $end mmfree */
  /* $begin mmfree */
  return bp;
}
/* $end mmfree */
/*
 * mm_realloc - Naive implementation of realloc
 */
void *mm_realloc(void *ptr, size_t size)
{
  size_t oldsize;
  void *newptr;
  /* If size == 0 then this is just free, and we return NULL. */
  if(size == 0) {
    mm_free(ptr);
    return 0;
  }
  /* If oldptr is NULL, then this is just malloc. */
  if(ptr == NULL) {
    return mm_malloc(size);
  }
  newptr = mm_malloc(size);
  /* If realloc() fails the original block is left untouched  */
  if(!newptr) {
    return 0;
  }
  /* Copy the old data. */
  oldsize = GET_SIZE(HDRP(ptr));
  if(size < oldsize) oldsize = size;
  memcpy(newptr, ptr, oldsize);
  /* Free the old block. */
  mm_free(ptr);
  return newptr;
}
/*
 * mm_checkheap - Check the heap for correctness
 */
void mm_checkheap(int verbose)
{
  checkheap(verbose);
}
/*
 * The remaining routines are internal helper routines
 */
/*
 * extend_heap - Extend heap with free block and return its block pointer
 */
/* $begin mmextendheap */
static void *extend_heap(size_t words)
{
  char *bp;
  size_t size;
  /* Allocate an even number of words to maintain alignment */
  size = (words % 2) ? (words+1) * WSIZE : words * WSIZE; //line:vm:mm:beginextend
  if ((long)(bp = mem_sbrk(size)) == -1)
    return NULL;                                        //line:vm:mm:endextend
  /* Initialize free block header/footer and the epilogue header */
  PUT(HDRP(bp), PACK(size, 0, GET_PREV_ALLOC(HDRP(bp))));         /* Free block header */   //line:vm:mm:freeblockhdr
  PUT(FTRP(bp), PACK(size, 0, GET_PREV_ALLOC(HDRP(bp))));         /* Free block footer */   //line:vm:mm:freeblockftr
  PUT(HDRP(NEXT_BLKP(bp)), PACK(0, 1, 0)); /* New epilogue header */ //line:vm:mm:newepihdr
  /* Coalesce if the previous block was free */
  return coalesce(bp);                                          //line:vm:mm:returnblock
}
/* $end mmextendheap */
/*
 * place - Place block of asize bytes at start of free block bp
 *         and split if remainder would be at least minimum block size
 */
/* $begin mmplace */
/* $begin mmplace-proto */
static void place(void *bp, size_t asize)
  /* $end mmplace-proto */
{
  size_t csize = GET_SIZE(HDRP(bp));
  if ((csize - asize) >= (2*DSIZE)) {
    PUT(HDRP(bp), PACK(asize, 1, 1));
    bp = NEXT_BLKP(bp);
    PUT(HDRP(bp), PACK(csize-asize, 0, 1));
    PUT(FTRP(bp), PACK(csize-asize, 0, 1));
  }
  else {
    PUT(HDRP(bp), PACK(csize, 1, 1));
    PUT(HDRP(NEXT_BLKP(bp)), PACK(csize, 1, 1));
  }
}
/* $end mmplace */
/*
 * find_fit - Find a fit for a block with asize bytes
 */
/* $begin mmfirstfit */
/* $begin mmfirstfit-proto */
static void *find_fit(size_t asize)
  /* $end mmfirstfit-proto */
{
  /* $end mmfirstfit */
  /* $begin mmfirstfit */
  /* First-fit search */
  void *bp;
  for (bp = heap_listp; GET_SIZE(HDRP(bp)) > 0; bp = NEXT_BLKP(bp)) {
    if (!GET_ALLOC(HDRP(bp)) && (asize <= GET_SIZE(HDRP(bp)))) {
      return bp;
    }
  }
  return NULL; /* No fit */
}
/* $end mmfirstfit */
static void printblock(void *bp)
{
  size_t hsize, halloc, fsize, falloc;
  checkheap(0);
  hsize = GET_SIZE(HDRP(bp));
  halloc = GET_ALLOC(HDRP(bp));
  fsize = GET_SIZE(FTRP(bp));
  falloc = GET_ALLOC(FTRP(bp));
  if (hsize == 0) {
    printf("%p: EOL\n", bp);
    return;
  }
  printf("%p: header: [%ld:%c] footer: [%ld:%c]\n", bp,
      hsize, (halloc ? 'a' : 'f'),
      fsize, (falloc ? 'a' : 'f'));
}
static void checkblock(void *bp)
{
  if ((size_t)bp % 8)
    printf("Error: %p is not doubleword aligned\n", bp);
  if (GET(HDRP(bp)) != GET(FTRP(bp)))
    printf("Error: header does not match footer\n");
}
/*
 * checkheap - Minimal check of the heap for consistency
 */
void checkheap(int verbose)
{
  char *bp = heap_listp;
  if (verbose)
    printf("Heap (%p):\n", heap_listp);
  if ((GET_SIZE(HDRP(heap_listp)) != DSIZE) || !GET_ALLOC(HDRP(heap_listp)))
    printf("Bad prologue header\n");
  checkblock(heap_listp);
  for (bp = heap_listp; GET_SIZE(HDRP(bp)) > 0; bp = NEXT_BLKP(bp)) {
    if (verbose)
      printblock(bp);
    checkblock(bp);
  }
  if (verbose)
    printblock(bp);
  if ((GET_SIZE(HDRP(bp)) != 0) || !(GET_ALLOC(HDRP(bp))))
    printf("Bad epilogue header\n");
}

P19

  • 1
    a a
  • 2
    d d
  • 3
    b b

P20

https://github.com/swy20190/CSAPP-3e-Solutions/blob/master/chapter9/9.20.md

第九章 完

发布了113 篇原创文章 · 获赞 73 · 访问量 19万+

猜你喜欢

转载自blog.csdn.net/swy_swy_swy/article/details/105295992