This assessment is CONFIDENTIAL. © University of Sydney Assignment 3 - friendship ended with malloc Due: 11:59PM Wednesday 28th April 2021 Sydney time This assignment is worth 15% of your final...

1 answer below »
Complete assignment quotation


This assessment is CONFIDENTIAL. © University of Sydney Assignment 3 - friendship ended with malloc Due: 11:59PM Wednesday 28th April 2021 Sydney time This assignment is worth 15% of your final assessment Task description In this assignment you will be implementing a simple dynamic memory allocator with a similar interface to the standard libary functions (such as malloc) that you are familiar with. You will be implementing your allocator as a library of functions that can be called by other programs, rather than as a standalone executable. Introduction The standard library and other real world allocator implementations obtain raw areas of memory from the kernel using the mmap and brk syscalls. Under a simplified memory model, these raw areas of memory are described as “the heap”. The allocator implements internal data structures that keep track of which parts of these raw blocks of memory are allocated or not. As you will be familiar, programs use library functions such as malloc and free to request dynamic memory from and return dynamic memory to the allocator. It is the allocator’s responsibility to use its internal data structures to mark memory that is allocated so that it does not overlap with any other allocations made, and to allow memory that is freed to be allocated to future dynamic memory requests. Furthermore, it is the allocator’s responsibility to appropriately call syscalls to obtain further memory from the operating system if required for an allocation, or to return memory to the operating system if it is no longer required. In this assignment, your allocator will manage a virtualised heap using a function we provide that simulates using brk to manipulate a real process heap. When dynamic memory is requested from your allocator, it will allocate it from this virtual “heap”. Memory allocation process Your virtual heap is simply a contiguous region of memory that you have read and write access to. Details on how you manage it are below in “Managing your Virtual Heap Memory”. You will implement a simple buddy allocation algorithm to manage your virtual heap. Buddy allocation fulfils all allocations from a starting block of memory that is 2n bytes in size, where n is a non-negative integer. During the allocation process, the starting memory is repeatedly halved, creating blocks of size 2i bytes where i is a non-negative integer and i < n.="" i="" also="" has="" a="" minimum="" value="" that="" we="" will="" refer="" to="" as="" min.="" allocation="" algorithm="" when="" a="" request="" for="" an="" allocation="" of="" k="" bytes="" of="" memory="" is="" made,="" follow="" this="" algorithm:="" 1.="" if="" there="" exists="" an="" unallocated="" block="" of="" size="" 2j="" bytes="" such="" that="" 2j-1="">< k="" ≤="" 2j,="" allocate="" and="" return="" the="" leftmost="" such="" unallocated="" block.="" exception:="" if="" there="" exists="" an="" unallocated="" block="" of="" size="" 2min="" and="" k="" ≤="" 2min,="" allocate="" and="" return="" the="" leftmost="" such="" block="" (because="" there="" are="" no="" smaller="" blocks="" to="" allocate)="" 2.="" if="" there="" exist="" no="" such="" unallocated="" blocks,="" create="" an="" unallocated="" block="" of="" size="" 2j="" bytes="" (if="" k="" ≤="" 2min,="" let="" j="MIN)" by="" the="" below="" steps="" 1="" 3.="" split="" the="" leftmost="" unallocated="" block="" of="" size="" 2j+1="" bytes="" in="" half.="" allocate="" and="" return="" the="" left="" half="" for="" this="" request.="" the="" right="" half="" becomes="" a="" free="" unallocated="" block="" of="" size="" 2j.="" blocks="" which="" are="" split="" are="" not="" allocatable.="" the="" 2="" child="" blocks="" which="" result="" from="" a="" split="" are="" called="" buddies="" of="" each="" other.="" 4.="" if="" no="" unallocated="" block="" of="" size="" 2j+1="" exists,="" repeat="" the="" last="" step="" with="" the="" leftmost="" unallocated="" block="" of="" size="" 2j+2,="" and="" so="" on="" as="" required,="" up="" to="" splitting="" the="" original="" block="" of="" 2n="" bytes.="" 5.="" if="" no="" block="" of="" suitable="" size="" can="" be="" found,="" return="" an="" appropriate="" error="" as="" described="" below="" in="" the="" functions="" you="" have="" to="" implement="" note="" the="" following:="" •="" the="" entire="" unallocated="" block="" is="" allocated="" for="" the="" request.="" in="" buddy="" allocation,="" there="" is="" often="" some="" wasted="" space="" because="" requested="" memory="" is="" less="" than="" the="" appropriate="" power-of-2="" block="" size.="" •="" “left”="" refers="" to="" smaller="" memory="" addresses="" •="" any="" area="" of="" memory="" can="" only="" be="" allocated="" once.="" if="" allocation="" succeeds,="" callers="" will="" expect="" to="" have="" exclusive="" access,="" at="" the="" pointer="" you="" return,="" to="" the="" number="" of="" bytes="" of="" memory="" they="" requested.="" •="" size="" limits="" are="" defined="" by="" the="" types="" we="" have="" specified="" for="" the="" functions="" you="" implement.="" deallocation="" algorithm="" when="" a="" previously="" allocated="" block="" of="" memory="" of="" size="" 2j="" bytes="" is="" requested="" to="" be="" freed,="" follow="" this="" algorithm:="" 1.="" if="" the="" buddy="" block="" of="" the="" freed="" block="" is="" also="" unallocated,="" merge="" the="" two="" buddies="" to="" form="" an="" unallocated="" block="" of="" size="" 2j+1.="" 2.="" repeat="" the="" previous="" step="" if="" the="" buddy="" block="" of="" this="" new="" 2j+1="" block="" is="" also="" unallocated.="" continue="" until="" no="" more="" unallo-="" cated="" buddy="" blocks="" can="" be="" merged.="" note="" the="" following:="" •="" unallocated="" buddy="" blocks="" which="" have="" been="" merged="" are="" no="" longer="" eligible="" for="" allocation,="" only="" the="" new="" parent="" unallo-="" cated="" block="" can="" be="" allocated="" (unless="" it="" is="" split="" up="" again)="" reallocation="" algorithm="" when="" an="" allocated="" piece="" of="" memory="" is="" requested="" to="" be="" reallocated,="" follow="" this="" algorithm:="" 1.="" make="" a="" new="" request="" for="" allocation="" at="" the="" new="" requested="" size,="" computing="" as="" if="" the="" previous="" piece="" of="" memory="" is="" freed="" 2.="" if="" the="" new="" allocation="" succeeds,="" the="" original="" data="" in="" the="" previous="" piece="" of="" memory="" should="" be="" made="" available="" at="" the="" new="" allocated="" block="" according="" to="" the="" details="" for="" the="" virtual_realloc="" function="" below="" 3.="" if="" the="" new="" allocation="" fails,="" the="" original="" allocation="" must="" be="" unchanged="" managing="" your="" virtual="" heap="" memory="" all="" functions="" that="" you="" have="" to="" implement="" accept="" a="" heapstart="" parameter,="" which="" is="" a="" pointer="" to="" the="" start="" of="" the="" contiguous="" region="" of="" memory="" that="" represents="" your="" virtual="" heap.="" your="" code="" can="" call="" a="" virtual_sbrk="" function="" that="" you="" can="" use="" to="" determine="" and="" change="" the="" size="" of="" your="" virtual="" heap="" space,="" analogously="" to="" the="" real-world="" sbrk="" and="" brk="" syscalls;="" its="" prototype="" is="" below.="" you="" do="" not="" need="" to="" use="" the="" real="" sbrk="" or="" brk="" for="" this="" assignment.="" void="" *="" virtual_sbrk(int32_t="" increment);="" the="" “program="" break”="" of="" your="" virtual="" heap="" refers="" to="" the="" address="" of="" the="" first="" byte="" after="" the="" end="" of="" your="" heap.="" (for="" the="" avoidance="" of="" doubt,="" “program="" break”="" in="" this="" document="" always="" refers="" to="" your="" virtual="" heap,="" and="" not="" any="" real="" program="" break="" of="" your="" process="" memory="" layout).="" 2="" the="" increment="" parameter="" indicates="" the="" number="" of="" bytes="" to="" increase="" (positive="" increment)="" or="" decrease="" the="" virtual="" heap="" size,="" by="" changing="" the="" program="" break="" by="" the="" same="" amount.="" if="" the="" call="" is="" successful,="" virtual_sbrk="" returns="" the="" previous="" program="" break="" of="" your="" virtual="" heap.="" if="" the="" call="" is="" unsuccessful="" (for="" example="" because="" the="" virtual="" heap="" cannot="" increase="" further="" in="" size),="" virtual_sbrk="" returns="" (void="" *)(-1)="" (errno="" is="" not="" set).="" if="" virtual_sbrk="" indicates="" it="" cannot="" increase="" your="" virtual="" heap="" space="" and="" this="" would="" cause="" your="" allocation="" to="" fail,="" then="" you="" should="" return="" the="" appropriate="" error="" for="" your="" function.="" functions="" to="" implement="" implement="" the="" following="" functions="" for="" your="" allocator.="" do="" not="" write="" any="" main()="" function.="" other="" programs="" will="" directly="" call="" your="" functions.="" void="" init_allocator(void="" *="" heapstart,="" uint8_t="" initial_size,="" uint8_t="" min_size);="" this="" function="" will="" be="" called="" exactly="" once="" before="" any="" other="" functions="" in="" your="" allocator="" are="" called.="" in="" this="" function,="" initialise="" your="" buddy="" allocation="" data="" structures="" and="" complete="" any="" preparation="" in="" the="" virtual="" heap="" memory="" you="" have="" been="" provided.="" this="" will="" be="" passed="" to="" each="" of="" your="" allocator="" functions,="" using="" the="" heapstart="" pointer="" only.="" you="" cannot="" pass="" any="" other="" state="" between="" your="" functions="" other="" than="" what="" is="" in="" your="" virtual="" heap.="" you="" may="" not="" use="" the="" standard="" library’s="" dynamic="" memory="" (such="" as="" malloc),="" or="" global="" variables,="" or="" files="" (even="" if="" you="" store="" pointers="" to="" external="" memory="" within="" your="" virtual="" heap).="" your="" buddy="" allocator="" starts="" with="" an="" initial="" unallocated="" block="" of="" memory="" of="" 2initial_size="" bytes.="" the="" minimum="" size="" of="" allocatable="" blocks="" will="" be="" 2min_size.="" it="" is="" up="" to="" you="" how="" you="" lay="" out="" your="" data="" structures="" in="" your="" virtual="" heap,="" but="" it="" must="" semantically="" behave="" as="" the="" buddy="" allocator="" described="" above.="" use="" virtual_sbrk="" to="" set="" your="" virtual="" heap="" size="" as="" you="" require.="" void="" *="" virtual_malloc(void="" *="" heapstart,="" uint32_t="" size);="" request="" an="" allocation="" from="" your="" allocator="" of="" size="" bytes.="" follow="" the="" buddy="" allocation="" algorithm="" outlined="" to="" return="" a="" pointer="" to="" the="" block="" of="" memory="" that="" you="" have="" allocated="" for="" the="" caller.="" return="" null="" if="" you="" cannot="" fulfil="" the="" allocation="" or="" if="" size="" is="" 0.="" newly="" allocated="" memory="" does="" not="" need="" to="" be="" initialised.="" int="" virtual_free(void="" *="" heapstart,="" void="" *="" ptr);="" ptr="" is="" a="" pointer="" to="" a="" previously="" allocated="" block="" of="" memory.="" your="" allocator="" should="" free="" the="" allocation="" according="" to="" the="" buddy="" allocation="" algorithm="" above.="" if="" successful,="" return="" 0.="" if="" ptr="" is="" not="" a="" pointer="" to="" a="" block="" of="" memory="" that="" was="" previously="" allocated,="" return="" non-zero.="" void="" *="" virtual_realloc(void="" *="" heapstart,="" void="" *="" ptr,="" uint32_t="" size);="" resize="" a="" previously="" allocated="" block="" of="" memory="" pointed="" to="" by="" ptr="" to="" a="" new="" size="" of="" size="" bytes,="" according="" to="" the="" buddy="" allocation="" algorithm="" above.="" the="" contents="" of="" the="" new="" block="" of="" memory="" should="" be="" identical="" to="" the="" old.="" if="" the="" size="" is="" smaller,="" the="" contents="" should="" be="" truncated.="" if="" the="" size="" is="" larger,="" the="" newly="" added="" memory="" region="" does="" not="" need="" to="" be="" initialised.="" return="" the="" pointer="" to="" the="" new="" allocation="" (which="" may="" be="" identical="" to="" ptr).="" return="" null="" if="" you="" cannot="" fulfil="" the="" reallocation.="" in="" this="" case,="" the="" previously="" allocated="" block="" of="" memory="" should="" not="" be="" freed="" and="" should="" be="" unchanged.="" if="" ptr="" is="" null,="" you="" should="" behave="" as="" if="" virtual_malloc(size)="" was="" called.="" if="" size="" is="" 0="" (including="" if="" ptr="" is="" null="" in="" this="" case),="" you="" should="" behave="" as="" if="" virtual_free(ptr)="" was="" called="" (always="" return="" null,="" even="" if="" the="" free="" would="" fail).="" void="" virtual_info(void="" *="" heapstart);="" print="" out="" information="" about="" the="" current="" state="" of="" your="" buddy="" allocator="" to="" standard="" output.="" output="" one="" line="" per="" allocatable="" block,="" allocated="" or="" unallocated,="" from="" “left”="" to="" “right”,="" in="" the="" following="" format:=""> . Allocation status is either allocated or free and size is in bytes (of the entire block). 3 Example Suppose that heapstart = 0x1000 and init_allocator is called with initial_size = 15 and min_size = 12. The diagram below shows the initial state of the virtual heap. Note that the space and location of your data structures is up to you and depends on your implementation of the buddy allocator. Note that virtual_sbrk has been used to set the virtual program break appropriately to fit what is being placed on the virtual heap. Suppose that virtual_malloc(heapstart, 8000) is called. 212 < 8000="" ≤="" 213,="" but="" we="" only="" have="" an="" unallocated="" block="" of="" size="" 215.="" therefore,="" we="" split="" the="" starting="" block="" in="" half="" twice,="" then="" allocate="" the="" leftmost="" block="" of="" size="" 213="" for="" this="" request.="" the="" address="" of="" this="" block="" is="" returned="" to="" the="" caller.="" suppose="" that="" virtual_malloc(heapstart,="" 10000)="" is="" called.="" 213="">< 10000 ≤ 214, so we allocate our only unallocated 214 block and return its address to the caller. 4 at this stage, if virtual_info(heapstart) was called, we expect the output: allocated 8192 free 8192 allocated 16384 suppose the allocated 213 block were freed. it will merge with its unallocated buddy to the right, forming an unallocated 214 size block. however 10000="" ≤="" 214,="" so="" we="" allocate="" our="" only="" unallocated="" 214="" block="" and="" return="" its="" address="" to="" the="" caller.="" 4="" at="" this="" stage,="" if="" virtual_info(heapstart)="" was="" called,="" we="" expect="" the="" output:="" allocated="" 8192="" free="" 8192="" allocated="" 16384="" suppose="" the="" allocated="" 213="" block="" were="" freed.="" it="" will="" merge="" with="" its="" unallocated="" buddy="" to="" the="" right,="" forming="" an="" unallocated="" 214="" size="" block.="">
Answered 4 days AfterApr 30, 2021

Answer To: This assessment is CONFIDENTIAL. © University of Sydney Assignment 3 - friendship ended with malloc...

Kamal answered on May 04 2021
139 Votes
code-submission/.git/COMMIT_EDITMSG
push1
code-submission/.git/config
[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
    ignorecase = true
    precomposeunicode = true
[remote "origin"]
    url = git.edstem.org:challenge/33054/code-submission
    fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
    remote = origin
    merge = refs/heads/master
code-submission/.git/description
Unnamed repository; edit this file 'description' to name the repository.
code-submission/.git/HEAD
ref: refs/heads/master
code-submission/.git/hooks/applypatch-msg.sample
#!/bin/sh
#
# An example hook script to check the commit log message taken by
# applypatch from an e-mail message.
#
# The hook sho
uld exit with non-zero status after issuing an
# appropriate message if it wants to stop the commit. The hook is
# allowed to edit the commit message file.
#
# To enable this hook, rename this file to "applypatch-msg".
. git-sh-setup
commitmsg="$(git rev-parse --git-path hooks/commit-msg)"
test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"}
:
code-submission/.git/hooks/commit-msg.sample
#!/bin/sh
#
# An example hook script to check the commit log message.
# Called by "git commit" with one argument, the name of the file
# that has the commit message. The hook should exit with non-zero
# status after issuing an appropriate message if it wants to stop the
# commit. The hook is allowed to edit the commit message file.
#
# To enable this hook, rename this file to "commit-msg".
# Uncomment the below to add a Signed-off-by line to the message.
# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
# hook is more suited to it.
#
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
# This example catches duplicate Signed-off-by lines.
test "" = "$(grep '^Signed-off-by: ' "$1" |
     sort | uniq -c | sed -e '/^[     ]*1[     ]/d')" || {
    echo >&2 Duplicate Signed-off-by lines.
    exit 1
}
code-submission/.git/hooks/fsmonitor-watchman.sample
#!/usr/bin/perl
use strict;
use warnings;
use IPC::Open2;
# An example hook script to integrate Watchman
# (https://facebook.github.io/watchman/) with git to speed up detecting
# new and modified files.
#
# The hook is passed a version (currently 1) and a time in nanoseconds
# formatted as a string and outputs to stdout all files that have been
# modified since the given time. Paths must be relative to the root of
# the working tree and separated by a single NUL.
#
# To enable this hook, rename this file to "query-watchman" and set
# 'git config core.fsmonitor .git/hooks/query-watchman'
#
my ($version, $time) = @ARGV;
# Check the hook interface version
if ($version == 1) {
    # convert nanoseconds to seconds
    $time = int $time / 1000000000;
} else {
    die "Unsupported query-fsmonitor hook version '$version'.\n" .
     "Falling back to scanning...\n";
}
my $git_work_tree;
if ($^O =~ 'msys' || $^O =~ 'cygwin') {
    $git_work_tree = Win32::GetCwd();
    $git_work_tree =~ tr/\\/\//;
} else {
    require Cwd;
    $git_work_tree = Cwd::cwd();
}
my $retry = 1;
launch_watchman();
sub launch_watchman {
    my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty')
     or die "open2() failed: $!\n" .
     "Falling back to scanning...\n";
    # In the query expression below we're asking for names of files that
    # changed since $time but were not transient (ie created after
    # $time but no longer exist).
    #
    # To accomplish this, we're using the "since" generator to use the
    # recency index to select candidate nodes and "fields" to limit the
    # output to file names only. Then we're using the "expression" term to
    # further constrain the results.
    #
    # The category of transient files that we want to ignore will have a
    # creation clock (cclock) newer than $time_t value and will also not
    # currently exist.
    my $query = <<"    END";
        ["query", "$git_work_tree", {
            "since": $time,
            "fields": ["name"],
            "expression": ["not", ["allof", ["since", $time, "cclock"], ["not", "exists"]]]
        }]
    END
    print CHLD_IN $query;
    close CHLD_IN;
    my $response = do {local $/; };
    die "Watchman: command returned no output.\n" .
     "Falling back to scanning...\n" if $response eq "";
    die "Watchman: command returned invalid output: $response\n" .
     "Falling back to scanning...\n" unless $response =~ /^\{/;
    my $json_pkg;
    eval {
        require JSON::XS;
        $json_pkg = "JSON::XS";
        1;
    } or do {
        require JSON::PP;
        $json_pkg = "JSON::PP";
    };
    my $o = $json_pkg->new->utf8->decode($response);
    if ($retry > 0 and $o->{error} and $o->{error} =~ m/unable to resolve root .* directory (.*) is not watched/) {
        print STDERR "Adding '$git_work_tree' to watchman's watch list.\n";
        $retry--;
        qx/watchman watch "$git_work_tree"/;
        die "Failed to make watchman watch '$git_work_tree'.\n" .
         "Falling back to scanning...\n" if $? != 0;
        # Watchman will always return all files on the first query so
        # return the fast "everything is dirty" flag to git and do the
        # Watchman query just to get it over with now so we won't pay
        # the cost in git to look up each individual file.
        print "/\0";
        eval { launch_watchman() };
        exit 0;
    }
    die "Watchman: $o->{error}.\n" .
     "Falling back to scanning...\n" if $o->{error};
    binmode STDOUT, ":utf8";
    local $, = "\0";
    print @{$o->{files}};
}
code-submission/.git/hooks/post-update.sample
#!/bin/sh
#
# An example hook script to prepare a packed repository for use over
# dumb transports.
#
# To enable this hook, rename this file to "post-update".
exec git update-server-info
code-submission/.git/hooks/pre-applypatch.sample
#!/bin/sh
#
# An example hook script to verify what is about to be committed
# by applypatch from an e-mail message.
#
# The hook should exit with non-zero status after issuing an
# appropriate message if it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-applypatch".
. git-sh-setup
precommit="$(git rev-parse --git-path hooks/pre-commit)"
test -x "$precommit" && exec "$precommit" ${1+"$@"}
:
code-submission/.git/hooks/pre-commit.sample
#!/bin/sh
#
# An example hook script to verify what is about to be committed.
# Called by "git commit" with no arguments. The hook should
# exit with non-zero status after issuing an appropriate message if
# it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-commit".
if git rev-parse --verify HEAD >/dev/null 2>&1
then
    against=HEAD
else
    # Initial commit: diff against an empty tree object
    against=$(git hash-object -t tree /dev/null)
fi
# If you want to allow non-ASCII filenames set this variable to true.
allownonascii=$(git config --bool hooks.allownonascii)
# Redirect output to stderr.
exec 1>&2
# Cross platform projects tend to avoid non-ASCII filenames; prevent
# them from being added to the repository. We exploit the fact that the
# printable range starts at the space character and ends with tilde.
if [ "$allownonascii" != "true" ] &&
    # Note that the use of brackets around a tr range is ok here, (it's
    # even required, for portability to Solaris 10's /usr/bin/tr), since
    # the square bracket bytes happen to fall in the designated range.
    test $(git diff --cached --name-only --diff-filter=A -z $against...
SOLUTION.PDF

Answer To This Question Is Available To Download

Related Questions & Answers

More Questions »

Submit New Assignment

Copy and Paste Your Assignment Here