#include "rassert.h"
struct pool_head core_table;
+
+#ifdef INDIRECT_CORE
+static uint8_t masks[8] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80};
+static uint8_t bits[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
+
+int n_core_blocks;
+int n_core_block_bitmap;
+uint8_t *core_block_bitmap;
+int core_block_next;
+int core_block_avail;
+
+int *core_table_mem;
+#endif
int *core_block_mem;
-void core_move(struct pool_item *item, int new_base) {
+static void core_move(struct pool_item *item, int new_base) {
int base = item->base;
int size = item->limit - base;
printf(
new_base,
new_base + size
);
- assert(new_base < base || new_base >= base + size);
+ assert(new_base <= base || new_base >= base + size);
for (int i = 0; i < size; ++i) {
+#ifdef INDIRECT_CORE
+ core_table_mem[new_base + i] = core_table_mem[base + i];
+ core_table_mem[base + i] = 0x55555555;
+#else
core_block_mem[new_base + i] = core_block_mem[base + i];
core_block_mem[base + i] = 0xaaaaaaaa;
+#endif
}
}
-void core_move_up(struct pool_item *item, int new_limit) {
+#ifdef MOVEABLE_CORE
+static void core_move_up(struct pool_item *item, int new_limit) {
int limit = item->limit;
- assert(limit != new_limit);
int neg_size = item->base - limit;
printf(
"core_move_up [%d,%d) to [%d,%d)\n",
new_limit + neg_size,
new_limit
);
- assert(new_limit > limit || new_limit <= limit + neg_size);
+ assert(new_limit >= limit || new_limit <= limit + neg_size);
for (int i = -1; i >= neg_size; --i) {
+#ifdef INDIRECT_CORE
+ core_table_mem[new_limit + i] = core_table_mem[limit + i];
+ core_table_mem[limit + i] = 0x55555555;
+#else
core_block_mem[new_limit + i] = core_block_mem[limit + i];
core_block_mem[limit + i] = 0xaaaaaaaa;
+#endif
}
}
+#endif
-void core_init(int table_size, int table_spare) {
+#ifdef INDIRECT_CORE
+void core_init(int table_size, int table_spare, int n_blocks)
+#else
+void core_init(int table_size, int table_spare)
+#endif
+{
pool_init(
&core_table,
0,
table_size,
table_spare,
core_move,
+#ifdef MOVEABLE_CORE
core_move_up
+#else
+ NULL
+#endif
);
+#ifdef INDIRECT_CORE
+ n_core_blocks = n_blocks;
+ n_core_block_bitmap = (n_core_blocks + 7) >> 3;
+ core_block_bitmap = malloc(n_core_block_bitmap);
+ rassert(core_block_bitmap);
+ memset(core_block_bitmap, 0xff, n_core_block_bitmap);
+ if (n_core_blocks & 7)
+ core_block_bitmap[n_core_blocks >> 3] = ~masks[n_core_blocks & 7];
+ core_block_next = 0;
+ core_block_avail = n_core_blocks;
+
+ core_table_mem = malloc(table_size * sizeof(int));
+ rassert(core_table_mem);
+ memset(core_table_mem, 0x55, table_size * sizeof(int));
+
+ core_block_mem = malloc(n_blocks * sizeof(int));
+ rassert(core_block_mem);
+ memset(core_block_mem, 0xaa, n_blocks * sizeof(int));
+#else
core_block_mem = malloc(table_size * sizeof(int));
+ rassert(core_block_mem);
memset(core_block_mem, 0xaa, table_size * sizeof(int));
+#endif
+}
+
+#ifdef INDIRECT_CORE
+bool core_block_alloc(int *table, int size) {
+ int i, j, k;
+ uint8_t c;
+
+ if (core_block_avail < size)
+ return false;
+
+ for (i = 0; i < size; ++i) {
+ j = core_block_next >> 3;
+ c = core_block_bitmap[j] & masks[core_block_next & 7];
+ goto loop_entry;
+ for (; j < n_core_block_bitmap; ++j) {
+ c = core_block_bitmap[j];
+ loop_entry:
+ if (c) goto found;
+ }
+#if 1
+ for (j = 0; ; ++j) {
+ assert(j <= core_block_next >> 3);
+ c = core_block_bitmap[j];
+ if (c) goto found;
+ }
+#else
+ k = (core_block_next >> 3) + 1;
+ for (j = 0; j < k; ++j) {
+ c = core_block_bitmap[j];
+ if (c) goto found;
+ }
+ core_block_free(table, i);
+ return false;
+#endif
+
+ found:
+ for (k = 0; (c & 1) == 0; ++k)
+ c >>= 1;
+ core_block_bitmap[j] &= ~bits[k];
+ core_block_next = (j << 3) | k;
+
+ assert(table[i] == 0x55555555);
+ table[i] = core_block_next++;
+ if (core_block_next >= n_core_blocks)
+ core_block_next = 0;
+ }
+
+ core_block_avail -= size;
+ return true;
+}
+
+void core_block_free(int *table, int size) {
+ int i, j, k;
+
+ for (i = 0; i < size; ++i) {
+ j = table[i];
+ assert(j >= 0 && j < n_core_blocks);
+ k = j & 7;
+ j >>= 3;
+ assert((core_block_bitmap[j] & bits[k]) == 0);
+ core_block_bitmap[j] |= bits[k];
+#ifndef NDEBUG
+ table[i] = 0x55555555;
+#endif
+ }
+
+ core_block_avail += size;
}
+#endif
#ifndef _CORE_H
#define _CORE_H 1
+#include <stdint.h>
#include "pool.h"
-#define MOVEABLE_CORE 1
+#define INDIRECT_CORE 1
+//#define MOVEABLE_CORE 1
#ifdef MOVEABLE_CORE
#define core_table_alloc(item, size) \
#endif
#define core_table_free(item) pool_free(&core_table, item)
+#ifdef INDIRECT_CORE
+#define core_avail() core_block_avail
+#else
+#define core_avail() core_table.avail
+#endif
+
extern struct pool_head core_table;
+
+#ifdef INDIRECT_CORE
+extern int n_core_blocks;
+int n_core_block_bitmap;
+extern uint8_t *core_block_bitmap;
+extern int core_block_next;
+extern int core_block_avail;
+
+extern int *core_table_mem;
+#endif
extern int *core_block_mem;
+#ifdef INDIRECT_CORE
+void core_init(int n_table, int table_spare, int n_blocks);
+bool core_block_alloc(int *blocks, int size);
+void core_block_free(int *blocks, int size);
+#else
void core_init(int n_table, int table_spare);
+#endif
#endif
# moveable swap (useable with any configuration):
#./process_test_run 16 64 0 192 0 16 <process_test.txt
# non moveable swap (must be preallocated, may be indirect):
-./process_test_run 16 64 0 384 0 16 192 <process_test.txt
+#./process_test_run 16 64 0 384 0 16 192 <process_test.txt
+# non moveable core and swap (must be preallocated, may be indirect):
+./process_test_run 16 384 0 384 0 16 64 192 <process_test.txt
#if 1
// won't work when compiled with NDEBUG
static void check_invariants() {
-#if defined(PREALLOCATE_CORE) && defined(PREALLOCATE_SWAP)
- int core_avail =
- core_table.item.base -
- core_table.item.limit -
- core_table.spare;
-#ifdef INDIRECT_SWAP
- int swap_avail = n_swap_blocks;
+ int avail =
+#ifdef INDIRECT_CORE
+ n_core_blocks +
#else
- int swap_avail =
- swap_table.item.base -
- swap_table.item.limit -
- swap_table.spare;
-#endif
- int avail = (
- core_avail < swap_avail ? core_avail : swap_avail
- ) - process_spare;
-#elif defined(PREALLOCATE_CORE)
- int core_avail =
core_table.item.base -
core_table.item.limit -
- core_table.spare;
- int avail = core_avail - process_spare;
-#elif defined(PREALLOCATE_SWAP)
-#ifdef INDIRECT_SWAP
- int swap_avail = n_swap_blocks;
-#else
- int swap_avail =
- swap_table.item.base -
- swap_table.item.limit -
- swap_table.spare;
+ core_table.spare +
#endif
- int avail = swap_avail - process_spare;
-#else
- int core_avail =
- core_table.item.base -
- core_table.item.limit -
- core_table.spare;
#ifdef INDIRECT_SWAP
- int swap_avail = n_swap_blocks;
+ n_swap_blocks -
#else
- int swap_avail =
swap_table.item.base -
swap_table.item.limit -
- swap_table.spare;
+ swap_table.spare -
#endif
- int avail = core_avail + swap_avail - process_spare;
+ process_spare;
+#if defined(PREALLOCATE_CORE)
+ if (
+ avail >
+ core_table.item.base -
+ core_table.item.limit -
+ core_table.spare
+ )
+ avail =
+ core_table.item.base -
+ core_table.item.limit -
+ core_table.spare;
+#endif
+#if defined(PREALLOCATE_SWAP)
+ if (
+ avail >
+ swap_table.item.base -
+ swap_table.item.limit -
+ swap_table.spare
+ )
+ avail =
+ swap_table.item.base -
+ swap_table.item.limit -
+ swap_table.spare;
#endif
if (victim == NULL) {
#ifdef PREALLOCATE_CORE
processes[i].size = -1;
#endif
-#if defined(PREALLOCATE_CORE) && defined(PREALLOCATE_SWAP)
-#ifdef INDIRECT_SWAP
- int swap_avail = n_swap_blocks;
-#else
- int swap_avail = swap_table.avail;
-#endif
- process_avail = (
- core_table.avail < swap_avail ? core_table.avail : swap_avail
- ) - spare;
-#elif defined(PREALLOCATE_CORE)
- process_avail = core_table.avail - spare;
-#elif defined(PREALLOCATE_SWAP)
-#ifdef INDIRECT_SWAP
- int swap_avail = n_swap_blocks;
-#else
- int swap_avail = swap_table.avail;
-#endif
- process_avail = swap_avail - spare;
-#else
-#ifdef INDIRECT_SWAP
- int swap_avail = n_swap_blocks;
-#else
- int swap_avail = swap_table.avail;
+ process_avail = core_avail() + swap_avail() - spare;
+#ifdef PREALLOCATE_CORE
+ if (process_avail > core_table.avail)
+ process_avail = core_table.avail;
#endif
- process_avail = core_table.avail + swap_avail - spare;
+#ifdef PREALLOCATE_SWAP
+ if (process_avail > swap_table.avail)
+ process_avail = swap_table.avail;
#endif
process_spare = spare;
rassert(swap_block_alloc(swap_table_mem + swap_base, size));
#endif
swap_write(swap_base, core_base, size);
+#ifdef INDIRECT_CORE
+ core_block_free(core_table_mem + core_base, size);
+#endif
// see if victim fully swapped out
victim_core_size -= size;
return false;
// free up as much core as we need to
- swap_out = size - core_table.avail;
-#ifndef PREALLOCATE_SWAP
- assert(swap_out <= swap_table.avail);
-#endif
+ swap_out = size - core_avail();
+ assert(swap_out <= swap_avail());
do_swap_out(swap_out);
// allocate core and possible swap
rassert(swap_table_alloc(&process->swap_item, size));
#endif
+#ifdef INDIRECT_CORE
+ // populate new table with physical blocks
+ rassert(
+ core_block_alloc(
+#ifdef PREALLOCATE_CORE
+ core_table_mem + process->core_item.base,
+#else
+ core_table_mem + process->pool_item.base,
+#endif
+ size
+ )
+ );
+#endif
+
// insert at head of LRU list
process->lru_item.prev = &lru_head;
process->lru_item.next = lru_head.next;
#endif
// free up as much core as we need to
- swap_out = size_change - core_table.avail;
-#ifndef PREALLOCATE_SWAP
- assert(swap_out <= swap_table.avail);
-#endif
+ swap_out = size_change - core_avail();
+ assert(swap_out <= swap_avail());
do_swap_out(swap_out);
// reallocate core and possible swap
rassert(swap_table_alloc(&process->swap_item, size));
#endif
+#ifdef INDIRECT_CORE
+ // populate new table with physical blocks or discard them
+ if (size_change >= 0)
+ rassert(
+ core_block_alloc(
+#ifdef PREALLOCATE_CORE
+ core_table_mem + process->core_item.limit - size_change,
+#else
+ core_table_mem + process->pool_item.limit - size_change,
+#endif
+ size_change
+ )
+ );
+ else
+ {
+ core_block_free(
+#ifdef PREALLOCATE_CORE
+ core_table_mem + process->core_item.limit,
+#else
+ core_table_mem + process->pool_item.limit,
+#endif
+ -size_change
+ );
+ }
+#endif
+
// track total allocation
process->size = size;
process_avail -= size_change;
// calculate amount to swap
size = process_swap_size;
- swap_out = size - core_table.avail;
- if (swap_out > swap_table.avail) {
- size += swap_table.avail - swap_out;
- swap_out = swap_table.avail;
+ swap_out = size - core_avail();
+ if (swap_out > swap_avail()) {
+ size += swap_avail() - swap_out;
+ swap_out = swap_avail();
}
// free up as much core as we can
-#ifndef PREALLOCATE_SWAP
- assert(swap_out <= swap_table.avail);
-#endif
+ assert(swap_out <= swap_avail());
do_swap_out(swap_out);
// add to core pool, using dedicated core item
#endif
// calculate how much to swap
size = process_swap_size;
- swap_out = size - core_table.avail;
- if (swap_out > swap_table.avail) {
- size += swap_table.avail - swap_out;
- swap_out = swap_table.avail;
+ swap_out = size - core_avail();
+ if (swap_out > swap_avail()) {
+ size += swap_avail() - swap_out;
+ swap_out = swap_avail();
}
// free up as much core as we can
core_base = process->core_item.base + process_core_size - size;
#else
core_base = process_core_item.limit - size;
+#endif
+#ifdef INDIRECT_CORE
+ core_block_alloc(core_table_mem + core_base, size);
#endif
swap_read(swap_base, core_base, size);
#ifdef INDIRECT_SWAP
process->lru_item.prev->next = process->lru_item.next;
process->lru_item.next->prev = process->lru_item.prev;
-#ifndef PREALLOCATE_CORE
+#ifdef PREALLOCATE_CORE
+#ifdef INDIRECT_SWAP
+ core_block_free(
+ core_table_mem + process->core_item.base,
+ process->core_item.limit - process->core_item.base
+ );
+#endif
+#else
+#ifdef INDIRECT_SWAP
+ core_block_free(
+ core_table_mem + process->pool_item.base,
+ process->pool_item.limit - process->pool_item.base
+ );
+#endif
core_table_free(&process->pool_item);
#endif
}
// victim, free the dedicated pool items
victim = NULL;
#ifdef PREALLOCATE_CORE
+#ifdef INDIRECT_CORE
+ core_block_free(
+ core_table_mem + process->core_item.base,
+ victim_core_size
+ );
+#endif
victim_core_size = 0;
#else
+#ifdef INDIRECT_CORE
+ core_block_free(
+ core_table_mem + victim_core_item.base,
+ victim_core_item.limit - victim_core_item.base
+ );
+#endif
core_table_free(&victim_core_item);
#endif
#ifdef PREALLOCATE_SWAP
#ifdef INDIRECT_SWAP
- printf("free 1\n");
swap_block_free(
swap_table_mem + ~(process->swap_item.base + victim_swap_size),
victim_swap_size
victim_swap_size = 0;
#else
#ifdef INDIRECT_SWAP
- printf("free 2\n");
swap_block_free(
swap_table_mem + ~victim_swap_item.limit,
victim_swap_item.limit - victim_swap_item.base
// fully in swap, remove from swap pool
#ifdef PREALLOCATE_SWAP
#ifdef INDIRECT_SWAP
- printf("free 3\n");
swap_block_free(
swap_table_mem + ~(process->swap_item.limit),
process->swap_item.limit - process->swap_item.base
#endif
#else
#ifdef INDIRECT_SWAP
- printf("free 4\n");
swap_block_free(
swap_table_mem + ~(process->pool_item.limit),
process->pool_item.limit - process->pool_item.base
#include "pool.h"
-//#define PREALLOCATE_CORE 1
+#define PREALLOCATE_CORE 1
#define PREALLOCATE_SWAP 1
struct lru_item {
int main(int argc, char **argv) {
if (argc < 7) {
-#ifdef INDIRECT_SWAP
+#if defined(INDIRECT_CORE) && defined(INDIRECT_SWAP)
+ printf("usage: %s n_processes core_table_size core_table_spare swap_table_size swap_table_spare spare [n_core_blocks [n_swap_blocks]]\n", argv[0]);
+#elif defined(INDIRECT_CORE)
+ printf("usage: %s n_processes core_table_size core_table_spare swap_table_size swap_table_spare spare [n_core_blocks]\n", argv[0]);
+#elif defined(INDIRECT_SWAP)
printf("usage: %s n_processes core_table_size core_table_spare swap_table_size swap_table_spare spare [n_swap_blocks]\n", argv[0]);
#else
printf("usage: %s n_processes core_table_size core_table_spare swap_table_size swap_table_spare spare\n", argv[0]);
int swap_table_size = atoi(argv[4]);
int swap_table_spare = atoi(argv[5]);
int spare = atoi(argv[6]);
-#ifdef INDIRECT_SWAP
+#if defined(INDIRECT_CORE) && defined(INDIRECT_SWAP)
+ int n_core_blocks = argc >= 8 ? atoi(argv[7]) : core_table_size;
+ int n_swap_blocks = argc >= 9 ? atoi(argv[8]) : swap_table_size;
+#elif defined(INDIRECT_CORE)
+ int n_core_blocks = argc >= 8 ? atoi(argv[7]) : core_table_size;
+#elif defined(INDIRECT_SWAP)
int n_swap_blocks = argc >= 8 ? atoi(argv[7]) : swap_table_size;
#endif
+#ifdef INDIRECT_CORE
+ core_init(core_table_size, core_table_spare, n_core_blocks);
+#else
core_init(core_table_size, core_table_spare);
+#endif
#ifdef INDIRECT_SWAP
swap_init(swap_table_size, swap_table_spare, n_swap_blocks);
#else
processes[i].size = -1;
while (true) {
- //printf("avail %d %d %d\n", process_avail, core_table.avail, swap_table.avail);
+ printf("avail %d %d(%d) %d(%d)\n", process_avail, core_avail(), core_table.avail, swap_avail(), swap_table.avail);
char buf[256];
switch (scanf("%s", buf)) {
case -1:
long long hash = process * 17 + i * 29;
hash = (hash & 0xffffffffffffffffLL) + (hash >> 32);
hash = (hash & 0xffffffffffffffffLL) + (hash >> 32);
- rassert(core_block_mem[core_base + i] == 0xaaaaaaaa);
- core_block_mem[core_base + i] = (int)hash;
+#ifdef INDIRECT_CORE
+ int core_block = core_table_mem[core_base + i];
+#else
+ int core_block = core_base + i;
+#endif
+ printf("%d\n", core_block);
+ rassert(core_block_mem[core_block] == 0xaaaaaaaa);
+ core_block_mem[core_block] = (int)hash;
}
#ifdef PREALLOCATE_SWAP
printf("new swap [%d,%d)\n", ~processes[process].swap_item.limit, ~processes[process].swap_item.base);
);
else {
#ifdef PREALLOCATE_CORE
- printf("old core [%d,%d)\n", processes[process].core_item.base, processes[process].core_item.limit);
+ int core_base = processes[process].core_item.base;
#else
- printf("old core [%d,%d)\n", processes[process].pool_item.base, processes[process].pool_item.limit);
-#endif
-#ifdef PREALLOCATE_SWAP
- printf("old swap [%d,%d)\n", ~processes[process].swap_item.limit, processes[process].swap_item.base);
+ int core_base = processes[process].pool_item.base;
#endif
int actual_old_size = processes[process].size;
rassert(actual_old_size <= old_size);
+ printf("old core [%d,%d)\n", core_base, core_base + actual_old_size);
+#ifdef PREALLOCATE_SWAP
+ printf("old swap [%d,%d)\n", ~processes[process].swap_item.limit, ~processes[process].swap_item.base);
+#endif
+ for (int i = size; i < actual_old_size; ++i) {
+ long long hash = process * 17 + i * 29;
+ hash = (hash & 0xffffffffffffffffLL) + (hash >> 32);
+ hash = (hash & 0xffffffffffffffffLL) + (hash >> 32);
+#ifdef INDIRECT_CORE
+ int core_block = core_table_mem[core_base + i];
+#else
+ int core_block = core_base + i;
+#endif
+ rassert(core_block_mem[core_block] == (int)hash);
+ core_block_mem[core_block] = 0xaaaaaaaa;
+ }
bool result = process_realloc(processes + process, size);
printf(
"realloc %d %d(%d) %d %d: %s\n",
}
else {
#ifdef PREALLOCATE_CORE
- int core_base = processes[process].core_item.base;
+ core_base = processes[process].core_item.base;
#else
- int core_base = processes[process].pool_item.base;
+ core_base = processes[process].pool_item.base;
#endif
printf("new core [%d,%d)\n", core_base, core_base + size);
for (int i = actual_old_size; i < size; ++i) {
long long hash = process * 17 + i * 29;
hash = (hash & 0xffffffffffffffffLL) + (hash >> 32);
hash = (hash & 0xffffffffffffffffLL) + (hash >> 32);
- rassert(core_block_mem[core_base + i] == 0xaaaaaaaa);
- core_block_mem[core_base + i] = (int)hash;
- }
- for (int i = size; i < actual_old_size; ++i) {
- long long hash = process * 17 + i * 29;
- hash = (hash & 0xffffffffffffffffLL) + (hash >> 32);
- hash = (hash & 0xffffffffffffffffLL) + (hash >> 32);
- rassert(core_block_mem[core_base + i] == (int)hash);
- core_block_mem[core_base + i] = 0xaaaaaaaa;
+#ifdef INDIRECT_CORE
+ int core_block = core_table_mem[core_base + i];
+#else
+ int core_block = core_base + i;
+#endif
+ rassert(core_block_mem[core_block] == 0xaaaaaaaa);
+ core_block_mem[core_block] = (int)hash;
}
#ifdef PREALLOCATE_SWAP
printf("new swap [%d,%d)\n", ~processes[process].swap_item.limit, ~processes[process].swap_item.base);
hash = (hash & 0xffffffffffffffffLL) + (hash >> 32);
hash = (hash & 0xffffffffffffffffLL) + (hash >> 32);
if (i < core_size) {
- rassert(core_block_mem[core_base + i] == (int)hash);
- core_block_mem[core_base + i] = 0xaaaaaaaa;
+#ifdef INDIRECT_CORE
+ int core_block = core_table_mem[core_base + i];
+#else
+ int core_block = core_base + i;
+#endif
+ rassert(core_block_mem[core_block] == (int)hash);
+ core_block_mem[core_block] = 0xaaaaaaaa;
}
else {
#ifdef INDIRECT_SWAP
hash = (hash & 0xffffffffffffffffLL) + (hash >> 32);
hash = (hash & 0xffffffffffffffffLL) + (hash >> 32);
if (j < core_size) {
- rassert(core_block_mem[core_base + j] == (int)hash);
- core_block_mem[core_base + j] = 0xaaaaaaaa;
+#ifdef INDIRECT_CORE
+ int core_block = core_table_mem[core_base + j];
+ core_table_mem[core_base + j] = 0x55555555;
+#else
+ int core_block = core_base + j;
+#endif
+ rassert(core_block_mem[core_block] == (int)hash);
+ core_block_mem[core_block] = 0xaaaaaaaa;
}
else {
#ifdef INDIRECT_SWAP
int swap_block = swap_table_mem[swap_base + j - core_size];
+ swap_table_mem[swap_base + j - core_size] = 0x55555555;
#else
int swap_block = swap_base + j - core_size;
#endif
}
for (int i = 0; i < core_table.item.base; ++i)
+#ifdef INDIRECT_CORE
+ rassert(core_table_mem[i] == 0x55555555);
+ for (int i = 0; i < n_core_blocks; ++i)
+#endif
rassert(core_block_mem[i] == 0xaaaaaaaa);
int swap_limit = ~swap_table.item.base;
for (int i = 0; i < swap_limit; ++i)
int n_swap_block_bitmap;
uint8_t *swap_block_bitmap;
int swap_block_next;
+int swap_block_avail;
int *swap_table_mem;
#endif
int *swap_block_mem;
-#ifdef MOVEABLE_SWAP
// swap address native wrt. pool and complemented wrt. backing store,
// means that swap_move() moves upward in backing store, do backward
static void swap_move(struct pool_item *item, int new_base) {
);
assert(new_limit >= limit || new_limit <= limit + neg_size);
for (int i = -1; i >= neg_size; --i) {
+#ifdef INDIRECT_SWAP
swap_table_mem[new_limit + i] = swap_table_mem[limit + i];
- swap_table_mem[limit + i] = 0xaaaaaaaa;
+ swap_table_mem[limit + i] = 0x55555555;
+#else
+ swap_block_mem[new_limit + i] = swap_block_mem[limit + i];
+ swap_block_mem[limit + i] = 0xaaaaaaaa;
+#endif
}
}
+#ifdef MOVEABLE_SWAP
// swap address native wrt. pool and complemented wrt. backing store,
// means that swap_move_up() moves downward in backing store, do forward
static void swap_move_up(struct pool_item *item, int new_limit) {
);
assert(new_base <= base || new_base >= base + size);
for (int i = 0; i < size; ++i) {
+#ifdef INDIRECT_SWAP
swap_table_mem[new_base + i] = swap_table_mem[base + i];
- swap_table_mem[base + i] = 0xaaaaaaaa;
+ swap_table_mem[base + i] = 0x55555555;
+#else
+ swap_block_mem[new_base + i] = swap_block_mem[base + i];
+ swap_block_mem[base + i] = 0xaaaaaaaa;
+#endif
}
}
#endif
~table_size,
-1,
table_spare,
-#ifdef MOVEABLE_SWAP
swap_move,
+#ifdef MOVEABLE_SWAP
swap_move_up
#else
- NULL,
NULL
#endif
);
swap_block_bitmap = malloc(n_swap_block_bitmap);
rassert(swap_block_bitmap);
memset(swap_block_bitmap, 0xff, n_swap_block_bitmap);
- if (n_blocks & 7)
+ if (n_swap_blocks & 7)
swap_block_bitmap[n_swap_blocks >> 3] = ~masks[n_swap_blocks & 7];
swap_block_next = 0;
+ swap_block_avail = n_swap_blocks;
swap_table_mem = malloc(table_size * sizeof(int));
rassert(swap_table_mem);
memset(swap_table_mem, 0x55, table_size * sizeof(int));
swap_block_mem = malloc(n_blocks * sizeof(int));
+ rassert(swap_block_mem);
+ memset(swap_block_mem, 0xaa, n_blocks * sizeof(int));
#else
swap_block_mem = malloc(table_size * sizeof(int));
-#endif
rassert(swap_block_mem);
- memset(swap_block_mem, 0xaa, n_blocks * sizeof(int));
+ memset(swap_block_mem, 0xaa, table_size * sizeof(int));
+#endif
}
#ifdef INDIRECT_SWAP
int i, j, k;
uint8_t c;
+ if (swap_block_avail < size)
+ return false;
+
for (i = 0; i < size; ++i) {
j = swap_block_next >> 3;
- c = swap_block_bitmap[j] & masks[j & 7];
+ c = swap_block_bitmap[j] & masks[swap_block_next & 7];
goto loop_entry;
for (; j < n_swap_block_bitmap; ++j) {
c = swap_block_bitmap[j];
loop_entry:
if (c) goto found;
}
+#if 1
+ for (j = 0; ; ++j) {
+ assert(j <= swap_block_next >> 3);
+ c = swap_block_bitmap[j];
+ if (c) goto found;
+ }
+#else
k = (swap_block_next >> 3) + 1;
for (j = 0; j < k; ++j) {
c = swap_block_bitmap[j];
if (c) goto found;
}
-
swap_block_free(table, i);
return false;
+#endif
found:
for (k = 0; (c & 1) == 0; ++k)
c >>= 1;
swap_block_bitmap[j] &= ~bits[k];
assert(table[i] == 0x55555555);
- j = (j << 3) | k;
- table[i] = j++;
- if (j >= n_swap_blocks)
- j = 0;
- swap_block_next = j;
+ swap_block_next = (j << 3) | k;
+
+ assert(table[i] == 0x55555555);
+ table[i] = swap_block_next++;
+ if (swap_block_next >= n_swap_blocks)
+ swap_block_next = 0;
}
+ swap_block_avail -= size;
return true;
}
table[i] = 0x55555555;
#endif
}
+
+ swap_block_avail += size;
}
#endif
#else
int swap_block = swap_base + i;
#endif
- assert(core_block_mem[core_base + i] == 0xaaaaaaaa);
- core_block_mem[core_base + i] = swap_block_mem[swap_block];
+#ifdef INDIRECT_CORE
+ int core_block = core_table_mem[core_base + i];
+ printf(",%d", core_block);
+#else
+ int core_block = core_base + i;
+#endif
+ assert(core_block_mem[core_block] == 0xaaaaaaaa);
+ core_block_mem[core_block] = swap_block_mem[swap_block];
swap_block_mem[swap_block] = 0xaaaaaaaa;
}
#ifdef INDIRECT_SWAP
printf("blocks");
#endif
for (int i = 0; i < size; ++i) {
+#ifdef INDIRECT_CORE
+ int core_block = core_table_mem[core_base + i];
+ printf(" %d", core_block);
+#else
+ int core_block = core_base + i;
+#endif
#ifdef INDIRECT_SWAP
int swap_block = swap_table_mem[swap_base + i];
- printf(" %d", swap_block);
+ printf(",%d", swap_block);
#else
int swap_block = swap_base + i;
#endif
assert(swap_block_mem[swap_block] == 0xaaaaaaaa);
- swap_block_mem[swap_block] = core_block_mem[core_base + i];
- core_block_mem[core_base + i] = 0xaaaaaaaa;
+ swap_block_mem[swap_block] = core_block_mem[core_block];
+ core_block_mem[core_block] = 0xaaaaaaaa;
}
#ifdef INDIRECT_SWAP
printf("\n");
#endif
#define swap_table_free(item) pool_free(&swap_table, item)
+#ifdef INDIRECT_SWAP
+#define swap_avail() swap_block_avail
+#else
+#define swap_avail() swap_table.avail
+#endif
+
extern struct pool_head swap_table;
#ifdef INDIRECT_SWAP
int n_swap_block_bitmap;
extern uint8_t *swap_block_bitmap;
extern int swap_block_next;
+extern int swap_block_avail;
extern int *swap_table_mem;
#endif