From abf62b06693de3792a816c04fdecfc763eac879f Mon Sep 17 00:00:00 2001 From: jdh8d <jdh8d@git.zephyr-software.com> Date: Fri, 14 Aug 2015 17:51:35 +0000 Subject: [PATCH] Added randomization of placed dollops. --- src/memory_space.cpp | 278 ++++++++++--------------------------------- src/zipr_options.cpp | 20 +++- 2 files changed, 79 insertions(+), 219 deletions(-) diff --git a/src/memory_space.cpp b/src/memory_space.cpp index b5856bc..aa4a89d 100644 --- a/src/memory_space.cpp +++ b/src/memory_space.cpp @@ -22,6 +22,11 @@ #include <unistd.h> #include <stdlib.h> #include <getopt.h> +#include <algorithm> // std::random_shuffle +#include <vector> // std::vector +#include <ctime> // std::time +#include <cstdlib> // std::rand, std::srand + using namespace zipr; using namespace std; @@ -56,7 +61,6 @@ void ZiprMemorySpace_t::SplitFreeRange(RangeAddress_t addr) } void ZiprMemorySpace_t::MergeFreeRange(RangeAddress_t addr) -#if 1 { /* * Make a new range of one byte. @@ -70,236 +74,65 @@ void ZiprMemorySpace_t::MergeFreeRange(RangeAddress_t addr) Range_t nr(addr, addr); Range_t nrp1(addr+1, addr+1); Range_t nrm1(addr-1, addr-1); - bool merged = false; RangeSet_t::iterator itp1; RangeSet_t::iterator itm1; -// for(;it!=free_ranges.end();++it) -// { - - itp1=free_ranges.find(nrp1); - itm1=free_ranges.find(nrm1); - Range_t r; - if(itp1!=free_ranges.end()) - { - r=*itp1; - assert((addr+1) == r.GetStart()); - /* - * Make the beginning of this range - * one byte smaller! - */ - Range_t nnr(addr, r.GetEnd()); - if(m_opts != NULL && m_opts->GetVerbose()) - { - printf("Expanded range:\n"); - printf("from: %p to %p\n", (void*)r.GetStart(), (void*)r.GetEnd()); - printf("to: %p to %p\n", (void*)nnr.GetStart(), (void*)nnr.GetEnd()); - } - nr = nnr; - if(itm1!=free_ranges.end()) - { - Range_t r2=*itm1; - nr.SetStart(r2.GetStart()); - free_ranges.erase(r2); - } - free_ranges.erase(r); - } - else if(itm1!=free_ranges.end()) // not addr+1 is still busy, so we don't merge against it. + itp1=free_ranges.find(nrp1); + itm1=free_ranges.find(nrm1); + Range_t r; + if(itp1!=free_ranges.end()) + { + r=*itp1; + assert((addr+1) == r.GetStart()); + /* + * Make the beginning of this range + * one byte smaller! + */ + Range_t nnr(addr, r.GetEnd()); + if(m_opts != NULL && m_opts->GetVerbose()) { - r=*itm1; - - assert((addr-1) == r.GetEnd()) ; - /* - * Make the end of this range one byte - * bigger - */ - Range_t nnr(r.GetStart(), addr); - if(m_opts != NULL && m_opts->GetVerbose()) - { - printf("Expanded range:\n"); - printf("from: %p to %p\n", (void*)r.GetStart(), (void*)r.GetEnd()); - printf("to: %p to %p\n", (void*)nnr.GetStart(), (void*)nnr.GetEnd()); - } - nr = nnr; - free_ranges.erase(itm1); + printf("Expanded range:\n"); + printf("from: %p to %p\n", (void*)r.GetStart(), (void*)r.GetEnd()); + printf("to: %p to %p\n", (void*)nnr.GetStart(), (void*)nnr.GetEnd()); } - else + nr = nnr; + if(itm1!=free_ranges.end()) { - // else both p1 and m1 are busy still, so we just insert nr + Range_t r2=*itm1; + nr.SetStart(r2.GetStart()); + free_ranges.erase(r2); } - - // insert NR and be done. - free_ranges.insert(nr); - return; -// } - - /* - * Correctness: - * Take a pass through and see if there are - * free ranges that can now be merged. This - * is important because it's possible that - * we added the byte to the end of a range - * where it could also have gone at the - * beginning of another. - */ -#if 0 - for(it=free_ranges.begin();it!=free_ranges.end();++it) + free_ranges.erase(r); + } + else if(itm1!=free_ranges.end()) // not addr+1 is still busy, so we don't merge against it. { - Range_t r = *it; - if (( - /* - * <--r--> - * <--nr--> - */ - ((r.GetEnd()+1) >= nr.GetStart() && - r.GetEnd() <= nr.GetEnd()) || - /* - * <--nr--> - * <--r--> - */ - ((nr.GetEnd()+1) >= r.GetStart() && - nr.GetEnd() <= r.GetEnd()) - ) && - /* - * The ranges themselves are not - * identical. - */ - (r.GetStart() != nr.GetStart() || - r.GetEnd() != nr.GetEnd())) + r=*itm1; + + assert((addr-1) == r.GetEnd()) ; + /* + * Make the end of this range one byte + * bigger + */ + Range_t nnr(r.GetStart(), addr); + if(m_opts != NULL && m_opts->GetVerbose()) { - /* - * merge. - */ - Range_t merged_range(std::min(r.GetStart(), nr.GetStart()), std::max(r.GetEnd(), nr.GetEnd())); - if(m_opts != NULL && m_opts->GetVerbose()) - { - printf("Merged two ranges:\n"); - printf("r: %p to %p\n", (void*)r.GetStart(), (void*)r.GetEnd()); - printf("nr: %p to %p\n", (void*)nr.GetStart(), (void*)nr.GetEnd()); - printf("to: %p to %p\n", (void*)merged_range.GetStart(), (void*)merged_range.GetEnd()); - } - free_ranges.erase(it); - free_ranges.insert(merged_range); - merged = true; - break; + printf("Expanded range:\n"); + printf("from: %p to %p\n", (void*)r.GetStart(), (void*)r.GetEnd()); + printf("to: %p to %p\n", (void*)nnr.GetStart(), (void*)nnr.GetEnd()); } + nr = nnr; + free_ranges.erase(itm1); } - - - if (!merged) + else { - free_ranges.insert(nr); + // else both p1 and m1 are busy still, so we just insert nr } -#endif -} -#else -{ - /* - * Make a new range of one byte. - * - * Then, look to see whether or not it - * can be merged with another range. - * - * If not, add it as a one byte range. - */ - - Range_t nr(addr, addr); - bool merged = false; - RangeSet_t::iterator it=free_ranges.begin(); - for(;it!=free_ranges.end();++it) - { - Range_t r=*it; - if ((addr+1) == r.GetStart()) { - /* - * Make the beginning of this range - * one byte smaller! - */ - Range_t nnr(addr, r.GetEnd()); - if(m_opts != NULL && m_opts->GetVerbose()) - { - printf("Expanded range:\n"); - printf("from: %p to %p\n", (void*)r.GetStart(), (void*)r.GetEnd()); - printf("to: %p to %p\n", (void*)nnr.GetStart(), (void*)nnr.GetEnd()); - } - nr = nnr; - free_ranges.erase(it); - break; - } else if ((addr-1) == r.GetEnd()) { - /* - * Make the end of this range one byte - * bigger - */ - Range_t nnr(r.GetStart(), addr); - if(m_opts != NULL && m_opts->GetVerbose()) - { - printf("Expanded range:\n"); - printf("from: %p to %p\n", (void*)r.GetStart(), (void*)r.GetEnd()); - printf("to: %p to %p\n", (void*)nnr.GetStart(), (void*)nnr.GetEnd()); - } - nr = nnr; - free_ranges.erase(it); - break; - } - } - - /* - * Correctness: - * Take a pass through and see if there are - * free ranges that can now be merged. This - * is important because it's possible that - * we added the byte to the end of a range - * where it could also have gone at the - * beginning of another. - */ - for(it=free_ranges.begin();it!=free_ranges.end();++it) - { - Range_t r = *it; - if (( - /* - * <--r--> - * <--nr--> - */ - ((r.GetEnd()+1) >= nr.GetStart() && - r.GetEnd() <= nr.GetEnd()) || - /* - * <--nr--> - * <--r--> - */ - ((nr.GetEnd()+1) >= r.GetStart() && - nr.GetEnd() <= r.GetEnd()) - ) && - /* - * The ranges themselves are not - * identical. - */ - (r.GetStart() != nr.GetStart() || - r.GetEnd() != nr.GetEnd())) - { - /* - * merge. - */ - Range_t merged_range(std::min(r.GetStart(), nr.GetStart()), std::max(r.GetEnd(), nr.GetEnd())); - if(m_opts != NULL && m_opts->GetVerbose()) - { - printf("Merged two ranges:\n"); - printf("r: %p to %p\n", (void*)r.GetStart(), (void*)r.GetEnd()); - printf("nr: %p to %p\n", (void*)nr.GetStart(), (void*)nr.GetEnd()); - printf("to: %p to %p\n", (void*)merged_range.GetStart(), (void*)merged_range.GetEnd()); - } - free_ranges.erase(it); - free_ranges.insert(merged_range); - merged = true; - break; - } - } + // insert NR and be done. + free_ranges.insert(nr); + return; - if (!merged) - { - free_ranges.insert(nr); - } } -#endif void ZiprMemorySpace_t::PrintMemorySpace(std::ostream &out) { @@ -325,15 +158,24 @@ bool ZiprMemorySpace_t::IsValidRange(RangeSet_t::iterator it) Range_t ZiprMemorySpace_t::GetFreeRange(int size) { + vector<Range_t> v; + Range_t big_range; for( RangeSet_t::iterator it=free_ranges.begin(); it!=free_ranges.end(); ++it) { Range_t r=*it; - if(r.GetEnd() - r.GetStart() > size) - return r; + if(r.GetEnd()==(RangeAddress_t)-1) + big_range=r;; + if(r.GetEnd() - r.GetStart() > (unsigned) size) + v.push_back(r); } - assert(0);// assume we find a big enough range. + if(v.size()==0) + return big_range; + + // choose random value to return. + int index=std::rand() % v.size(); + return v[index]; } // queries about free areas. diff --git a/src/zipr_options.cpp b/src/zipr_options.cpp index 6f8cdb6..7fcfb64 100644 --- a/src/zipr_options.cpp +++ b/src/zipr_options.cpp @@ -22,6 +22,11 @@ #include <unistd.h> #include <stdlib.h> #include <getopt.h> +#include <ctime> // std::time +#include <iostream> +#include <cstdlib> // std::srand + + using namespace zipr; @@ -51,7 +56,7 @@ ZiprOptions_t* ZiprOptions_t::parse_args(int p_argc, char* p_argv[]) ZiprOptions_t *opt=new ZiprOptions_t; opt->SetVerbose(true); int option = 0; - char options[] = "!qz:o:v:c:j:m:"; + char options[] = "!qz:o:v:c:j:m:s:"; struct option long_options[] = { {"verbose", no_argument, NULL, '!'}, {"quiet", no_argument, NULL, 'q'}, @@ -61,9 +66,13 @@ ZiprOptions_t* ZiprOptions_t::parse_args(int p_argc, char* p_argv[]) {"callbacks", required_argument, NULL, 'c'}, {"objcopy", required_argument, NULL, 'j'}, {"architecture",required_argument, NULL, 'm'}, + {"seed",required_argument, NULL, 's'}, {NULL, no_argument, NULL, '\0'}, // end-of-array marker }; + // set random seed for zipr to really random. + std::srand ( unsigned ( std::time(0) ) ); + assert(opt); while ((option = getopt_long( @@ -147,6 +156,15 @@ ZiprOptions_t* ZiprOptions_t::parse_args(int p_argc, char* p_argv[]) "Will use detection to determine architecture. \n", ::optarg); break; } + case 's': + { + char *valid = NULL; + long int seed = ::strtol(::optarg, &valid, 10); + if(*valid!='\0') + std::cerr<<"Seed value ("<< ::optarg << ") must be a base-10 integer."<<std::endl; + std::srand((unsigned)seed); + break; + } case '?': { // getopt_long printed message -- GitLab