Changeset 82

Show
Ignore:
Timestamp:
06/29/05 03:06:17 (4 years ago)
Author:
jtv
Message:

Redesigned policy state machine, now in its own file

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • debian/changelog

    r81 r82  
     1swapspace (1.5) unstable; urgency=low 
     2 
     3  * Redesigned internal state machine, should improve corner-case behaviour 
     4 
     5 -- Jeroen T. Vermeulen <jtv@sipa.or.th>  Wed, 29 June 2005 14:10:00 +0700 
     6 
    17swapspace (1.4) unstable; urgency=low 
    28 
  • src/Makefile

    r81 r82  
    99 
    1010 
    11 SWAPSPACEOBJS=log.o main.o memory.o opts.o support.o swaps.o 
     11SWAPSPACEOBJS=log.o main.o memory.o opts.o state.o support.o swaps.o 
    1212 
    1313swapspace : $(SWAPSPACEOBJS) 
     
    2424opts.o : opts.c opts.h main.h ../VERSION ../DATE 
    2525 
     26state.o : state.c state.h main.h memory.h support.h swaps.h 
     27 
    2628support.o : support.c config.h env.h support.h 
    2729 
    28 swaps.o : swaps.c config.h env.h log.h main.h memory.h support.h swaps.h 
     30swaps.o : swaps.c config.h env.h log.h main.h memory.h state.h support.h swaps.h 
    2931 
    3032clean : 
  • src/main.c

    r81 r82  
    3939#include "memory.h" 
    4040#include "opts.h" 
     41#include "state.h" 
    4142#include "support.h" 
    4243#include "swaps.h" 
     
    197198{ 
    198199  // TODO: TODO: TODO: 
    199 } 
    200  
    201  
    202 static void handle_requirements(void) 
    203 { 
    204   const memsize_t req = memory_target(); 
    205   if (req > 0)          alloc_swapfile(req); 
    206   else if (req < 0)     free_swapfile(-req); 
    207   else                  steady_state(); 
    208200} 
    209201 
  • src/swaps.c

    r81 r82  
    3636#include "log.h" 
    3737#include "opts.h" 
     38#include "state.h" 
    3839#include "support.h" 
    3940#include "swaps.h" 
     
    6970 
    7071 
    71 // TODO: Make this adaptive 
    72 /// Minimum cooldown time between Bull/Bear policy reversals 
    73 /** The program's disposition to allocate or deallocate wavers between two 
    74  * extremes: Bull and Bear.  This is done to avoid unstable behaviour where swap 
    75  * files are repeatedly created, deleted again, and then re-allocated. 
    76  * 
    77  * During Bull phases more swap space may be allocated to meet demand, but no 
    78  * deallocations are made regardless of how much swap or memory space is being 
    79  * left unused.  While this phase lasts, the program will assume that any drop 
    80  * in swap space usage may be temporary and the allocated swap files may be 
    81  * needed again soon.  Bull phases can end only if the disk fills up with swap 
    82  * files, or the amount of free memory remains above the deallocation threshold 
    83  * for an entire cooldown period. 
    84  * 
    85  * On the other extreme, Bear phases occur when swapfile allocation fails due 
    86  * to lack of disk space.  Once we get to that stage, allocating yet more swap 
    87  * space is not likely to satisfy whatever software is using up so much memory 
    88  * or disk space.  In a Bear phase we assume that the spike in memory usage is a 
    89  * fluke: no more allocations are attempted--hopefully starving the offending 
    90  * software--and unneeded swap space is freed up more aggressively. 
    91  * 
    92  * Deallocation does not trigger a transition, though it may conceivably provide 
    93  * useful information about optimal phase duration. 
    94  */ 
    95 static time_t cooldown_time = 600; 
    96  
    9772char *set_min_swapsize(long long size) 
    9873{ 
     
    10479{ 
    10580  max_swapsize = TRUNC_TO_PAGE(size); 
    106   return NULL; 
    107 } 
    108  
    109 char *set_cooldown(long long duration) 
    110 { 
    111   cooldown_time = (time_t)duration; 
    11281  return NULL; 
    11382} 
     
    142111 
    143112  return true; 
    144 } 
    145  
    146  
    147 /// Timestamp of most recent attempt to allocate a swapfile 
    148 static time_t cooldown_start = 0; 
    149  
    150 /// Did the last attempt at swapfile allocation trigger a Bear phase? 
    151 static bool cooldown_bear = false; 
    152  
    153  
    154 static inline bool in_cooldown(void) 
    155 { 
    156   return (clock < cooldown_start + cooldown_time); 
    157 } 
    158  
    159  
    160 void steady_state(void) 
    161 { 
    162   if (!cooldown_bear) cooldown_start = clock; 
    163113} 
    164114 
     
    197147  // TODO: Allow this to go to logfile 
    198148  printf("clock: %lld\t", (long long)clock); 
    199   if (cooldown_start != LONG_MIN) 
    200   { 
    201     printf("%s cooldown since %lld, ", 
    202         (cooldown_bear?"Bear":"Bull"), 
    203         (long long)cooldown_start); 
    204     const long long cooldown_end = cooldown_start + cooldown_time; 
    205     if (in_cooldown()) 
    206       printf("ended at %lld (%llds ago)\n",cooldown_end,clock-cooldown_end); 
    207     else 
    208       printf("ends at %lld (in %llds)\n",cooldown_end,cooldown_end-clock); 
    209   } 
     149  dump_state(); 
    210150 
    211151  // TODO: Print memory overview, and include percentages 
    212152 
    213   puts("swapfiles in use:\n" "file\tsize\tused"); 
     153  puts("swapfiles in use:\nfile\tsize\tused"); 
    214154  for (int i=0; i<MAX_SWAPFILES; ++i) 
    215155    if (swapfiles[i].size) 
     
    218158          swapfiles[i].size, 
    219159          swapfiles[i].used); 
     160  puts("---"); 
    220161} 
    221162 
     
    281222      // Disk full.  Don't create swapfiles for a while. 
    282223      bytes = 0; 
    283       cooldown_bear = true; 
    284       cooldown_start = clock; 
    285224      break; 
    286225    } 
    287   } 
    288   else 
    289   { 
    290     cooldown_start = clock; 
    291226  } 
    292227 
     
    315250  if (unlikely(size < min_swapsize)) return 0; 
    316251 
    317   // Don't allocate swap for a while--we had a bad experience recently 
    318   if (unlikely(cooldown_bear) && in_cooldown()) return 0; 
    319  
    320252  size = MIN(size, max_swapsize); 
    321253 
     
    332264  { 
    333265    unlink(file); 
    334     size = 0; 
     266    realsize = 0; 
    335267  } 
    336268   
     
    614546 
    615547 
    616 void alloc_swapfile(memsize_t size) 
     548bool alloc_swapfile(memsize_t size) 
    617549{ 
    618550  /* Round request to page size, then add a bit for swapfile overhead.  Clever 
     
    621553  size = TRUNC_TO_PAGE(size) + 2*PAGE_SIZE; 
    622554  const int newswap = find_free(sequence_number); 
    623   if (swapfiles[newswap].size) return;        // No free slot, sorry! 
     555  if (swapfiles[newswap].size) return false;  // No free slot, sorry! 
    624556 
    625557  // We can allocate another swapfile.  Great. 
     
    631563  if (swapfiles[newswap].size) 
    632564  { 
    633     if (enable_swapfile(file)) sequence_number = inc_swapno(sequence_number); 
    634     else unlink(file); 
    635   } 
     565    if (!enable_swapfile(file)) 
     566    { 
     567      unlink(file); 
     568      return false; 
     569    } 
     570    sequence_number = inc_swapno(sequence_number); 
     571  } 
     572 
     573  return true; 
    636574} 
    637575 
     
    639577void free_swapfile(memsize_t maxsize) 
    640578{ 
    641   if (cooldown_bear || !in_cooldown()) 
    642   { 
    643     const int victim = find_retirable(maxsize); 
    644     if (victim < MAX_SWAPFILES) retire_swapfile(victim); 
    645   } 
    646 
     579  const int victim = find_retirable(maxsize); 
     580  if (victim < MAX_SWAPFILES) retire_swapfile(victim); 
     581
  • src/swaps.h

    r81 r82  
    5454/** 
    5555 * @param size number of bytes to allocate 
     56 * @return success 
    5657 */ 
    57 void alloc_swapfile(memsize_t size); 
     58bool alloc_swapfile(memsize_t size); 
    5859 
    5960/// Free swap space 
     
    6263 */ 
    6364void free_swapfile(memsize_t maxsize); 
    64  
    65 /// Mark an iteration where we don't want to allocate/deallocate swap files  
    66 void steady_state(void); 
    6765 
    6866char *set_min_swapsize(long long size);