Changeset 82
- Timestamp:
- 06/29/05 03:06:17 (4 years ago)
- Files:
-
- debian/changelog (modified) (1 diff)
- src/Makefile (modified) (2 diffs)
- src/main.c (modified) (2 diffs)
- src/state.c (added)
- src/state.h (added)
- src/swaps.c (modified) (13 diffs)
- src/swaps.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
debian/changelog
r81 r82 1 swapspace (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 1 7 swapspace (1.4) unstable; urgency=low 2 8 src/Makefile
r81 r82 9 9 10 10 11 SWAPSPACEOBJS=log.o main.o memory.o opts.o s upport.o swaps.o11 SWAPSPACEOBJS=log.o main.o memory.o opts.o state.o support.o swaps.o 12 12 13 13 swapspace : $(SWAPSPACEOBJS) … … 24 24 opts.o : opts.c opts.h main.h ../VERSION ../DATE 25 25 26 state.o : state.c state.h main.h memory.h support.h swaps.h 27 26 28 support.o : support.c config.h env.h support.h 27 29 28 swaps.o : swaps.c config.h env.h log.h main.h memory.h s upport.h swaps.h30 swaps.o : swaps.c config.h env.h log.h main.h memory.h state.h support.h swaps.h 29 31 30 32 clean : src/main.c
r81 r82 39 39 #include "memory.h" 40 40 #include "opts.h" 41 #include "state.h" 41 42 #include "support.h" 42 43 #include "swaps.h" … … 197 198 { 198 199 // 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();208 200 } 209 201 src/swaps.c
r81 r82 36 36 #include "log.h" 37 37 #include "opts.h" 38 #include "state.h" 38 39 #include "support.h" 39 40 #include "swaps.h" … … 69 70 70 71 71 // TODO: Make this adaptive72 /// Minimum cooldown time between Bull/Bear policy reversals73 /** The program's disposition to allocate or deallocate wavers between two74 * extremes: Bull and Bear. This is done to avoid unstable behaviour where swap75 * 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 no78 * deallocations are made regardless of how much swap or memory space is being79 * left unused. While this phase lasts, the program will assume that any drop80 * in swap space usage may be temporary and the allocated swap files may be81 * needed again soon. Bull phases can end only if the disk fills up with swap82 * files, or the amount of free memory remains above the deallocation threshold83 * for an entire cooldown period.84 *85 * On the other extreme, Bear phases occur when swapfile allocation fails due86 * to lack of disk space. Once we get to that stage, allocating yet more swap87 * space is not likely to satisfy whatever software is using up so much memory88 * or disk space. In a Bear phase we assume that the spike in memory usage is a89 * fluke: no more allocations are attempted--hopefully starving the offending90 * software--and unneeded swap space is freed up more aggressively.91 *92 * Deallocation does not trigger a transition, though it may conceivably provide93 * useful information about optimal phase duration.94 */95 static time_t cooldown_time = 600;96 97 72 char *set_min_swapsize(long long size) 98 73 { … … 104 79 { 105 80 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;112 81 return NULL; 113 82 } … … 142 111 143 112 return true; 144 }145 146 147 /// Timestamp of most recent attempt to allocate a swapfile148 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;163 113 } 164 114 … … 197 147 // TODO: Allow this to go to logfile 198 148 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(); 210 150 211 151 // TODO: Print memory overview, and include percentages 212 152 213 puts("swapfiles in use:\n " "file\tsize\tused");153 puts("swapfiles in use:\nfile\tsize\tused"); 214 154 for (int i=0; i<MAX_SWAPFILES; ++i) 215 155 if (swapfiles[i].size) … … 218 158 swapfiles[i].size, 219 159 swapfiles[i].used); 160 puts("---"); 220 161 } 221 162 … … 281 222 // Disk full. Don't create swapfiles for a while. 282 223 bytes = 0; 283 cooldown_bear = true;284 cooldown_start = clock;285 224 break; 286 225 } 287 }288 else289 {290 cooldown_start = clock;291 226 } 292 227 … … 315 250 if (unlikely(size < min_swapsize)) return 0; 316 251 317 // Don't allocate swap for a while--we had a bad experience recently318 if (unlikely(cooldown_bear) && in_cooldown()) return 0;319 320 252 size = MIN(size, max_swapsize); 321 253 … … 332 264 { 333 265 unlink(file); 334 size = 0;266 realsize = 0; 335 267 } 336 268 … … 614 546 615 547 616 voidalloc_swapfile(memsize_t size)548 bool alloc_swapfile(memsize_t size) 617 549 { 618 550 /* Round request to page size, then add a bit for swapfile overhead. Clever … … 621 553 size = TRUNC_TO_PAGE(size) + 2*PAGE_SIZE; 622 554 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! 624 556 625 557 // We can allocate another swapfile. Great. … … 631 563 if (swapfiles[newswap].size) 632 564 { 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; 636 574 } 637 575 … … 639 577 void free_swapfile(memsize_t maxsize) 640 578 { 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 54 54 /** 55 55 * @param size number of bytes to allocate 56 * @return success 56 57 */ 57 voidalloc_swapfile(memsize_t size);58 bool alloc_swapfile(memsize_t size); 58 59 59 60 /// Free swap space … … 62 63 */ 63 64 void free_swapfile(memsize_t maxsize); 64 65 /// Mark an iteration where we don't want to allocate/deallocate swap files66 void steady_state(void);67 65 68 66 char *set_min_swapsize(long long size);
