int base, blocks;
#ifndef INDIRECT_CORE
struct process *process;
- int paras;
+ struct process_state state;
+ int para;
#else /* INDIRECT_CORE */
int i;
#endif /* INDIRECT_CORE */
blocks = item->limit - base;
printf("core_move [%d,%d) to [%d,%d)\n", base, base + blocks, new_base, new_base + blocks);
assert(new_base <= base || new_base >= base + blocks);
+
#ifndef INDIRECT_CORE
- // see if incomplete last block, if so don't copy extra part
- process =
- (struct process *)((char *)item - offsetof(struct process, core_item));
- paras = blocks << BLOCK_PARAS_SHIFT;
- if (paras > process->paras)
- paras = process->paras;
+#if 0 // debugging
+ core_copy(
+ base << BLOCK_PARAS_SHIFT,
+ new_base << BLOCK_PARAS_SHIFT,
+ blocks << BLOCK_PARAS_SHIFT
+ );
+#else
+ // figure out how much of item is valid
+ process = (struct process *)(
+ (char *)item - offsetof(struct process, core_item)
+ );
+ process_get_state(process, &state);
+ printf("old core [%d,%d) swap occupation [%d,%d)\n", state.core_base, state.core_base + state.core_blocks, state.swap_base, state.swap_base + state.swap_blocks);
- // copy by abstract routine
- core_copy(base << BLOCK_PARAS_SHIFT, new_base << BLOCK_PARAS_SHIFT, paras);
+ // copy valid part by abstract routine
+ para =
+ (state.core_base << BLOCK_PARAS_SHIFT) +
+ state.core_para;
+ core_copy(
+ para,
+ para + ((new_base - base) << BLOCK_PARAS_SHIFT),
+ state.core_paras
+ );
+#endif
+#else /* INDIRECT_CORE */
+ for (i = 0; i < blocks; ++i) {
+ core_table_mem[new_base + i] = core_table_mem[base + i];
+ core_table_mem[base + i] = 0x55555555;
+ }
+#endif
}
+#ifndef INDIRECT_CORE
static void core_move_up(struct pool_item *item, int new_limit) {
int limit, blocks;
- int limit1, new_limit1, paras;
struct process *process;
- int trim;
+ struct process_state state;
+ int para;
limit = item->limit;
blocks = limit - item->base;
printf("core_move_up [%d,%d) to [%d,%d)\n", limit - blocks, limit, new_limit - blocks, new_limit);
assert(new_limit >= limit || new_limit <= limit - blocks);
- // set up transfer parameters
- limit1 = limit << BLOCK_PARAS_SHIFT;
- new_limit1 = new_limit << BLOCK_PARAS_SHIFT;
- paras = blocks << BLOCK_PARAS_SHIFT;
- // see if incomplete last block, if so don't copy extra part
- process =
- (struct process *)((char *)item - offsetof(struct process, core_item));
- trim = paras - process->paras;
- if (trim > 0) {
- limit1 -= trim;
- new_limit1 -= trim;
- paras = process->paras;
-#else /* INDIRECT_CORE */
- for (i = 0; i < blocks; ++i) {
- core_table_mem[new_base + i] = core_table_mem[base + i];
- core_table_mem[base + i] = 0x55555555;
-#endif /* INDIRECT_CORE */
- }
+#if 0 // debugging
+ core_copy_up(
+ limit << BLOCK_PARAS_SHIFT,
+ new_limit << BLOCK_PARAS_SHIFT,
+ blocks << BLOCK_PARAS_SHIFT
+ );
+#else
+ // figure out how much of item is valid
+ process = (struct process *)(
+ (char *)item - offsetof(struct process, core_item)
+ );
+ process_get_state(process, &state);
+ printf("old core [%d,%d) swap occupation [%d,%d)\n", state.core_base, state.core_base + state.core_blocks, state.swap_base, state.swap_base + state.swap_blocks);
-#ifndef INDIRECT_CORE
- // copy by abstract routine
- core_copy_up(limit1, new_limit1, paras);
-#endif /* ! INDIRECT_CORE */
+ // copy valid part by abstract routine
+ para =
+ (state.core_base << BLOCK_PARAS_SHIFT) +
+ state.core_para +
+ state.core_paras;
+ core_copy_up(
+ para,
+ para + ((new_limit - limit) << BLOCK_PARAS_SHIFT),
+ state.core_paras
+ );
+#endif
}
+#endif /* ! INDIRECT_CORE */
#ifndef INDIRECT_CORE
void core_init(int n_blocks)
#!/bin/sh
echo "generate test script"
-./process_test_gen 16 248 1024 32 >process_test.txt
+./process_test_gen 16 248 1024 32 true true >process_test.txt
echo "run test script"
./process_test_run 16 64 192 8 384 384 <process_test.txt
int main(int argc, char **argv) {
if (argc < 5) {
- printf("usage: %s n_items pool_size n_events item_size [base [seed]]\n", argv[0]);
+ printf("usage: %s n_items pool_size n_events item_size [do_base [seed]]\n", argv[0]);
exit(EXIT_FAILURE);
}
int n_items = atoi(argv[1]);
int pool_size = atoi(argv[2]);
int n_events = atoi(argv[3]);
int item_size = atoi(argv[4]);
- bool base = argc >= 6 ? strcmp(argv[5], "false") != 0 : false;
+ bool do_base = argc >= 6 ? strcmp(argv[5], "false") != 0 : false;
int seed = argc >= 7 ? atoi(argv[6]) : 1;
int *items = malloc(n_items * sizeof(int));
bool success = pool_used + size - old_size <= pool_size;
printf(
"realloc%s %d %d %d %s\n",
- base && rand_int(3) == 0 ? "_base" : "",
+ do_base && rand_int(3) == 0 ? "_base" : "",
item,
old_size,
size,
struct lru_item lru_head;
+struct process *runner;
+int runner_swap_blocks;
+
struct process *victim;
int victim_swap_blocks;
return true;
}
-bool process_alloc(struct process *process, int paras) {
+bool process_alloc(struct process *process, int para, int paras) {
int blocks;
// must not be already allocated
assert(process->paras == -1);
// check blocks
- blocks = (paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT;
+ blocks = (para + paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT;
if (
process_avail < blocks ||
!pool_alloc(
process->lru_item.next->prev = &process->lru_item;
// track total allocation
+ process->para = para;
process->paras = paras;
process_avail -= blocks;
return true;
}
-bool process_realloc(struct process *process, int paras) {
- int old_blocks, blocks, blocks_change;
+bool process_realloc(struct process *process, int paras, bool dir) {
+ int old_blocks, para, blocks, blocks_change;
// must be already allocated
assert(process->paras != -1);
// check blocks
old_blocks = process->swap_item.limit - process->swap_item.base;
- blocks = (paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT;
+ para = process->para;
+ if (dir)
+ para = (old_blocks << BLOCK_PARAS_SHIFT) - para - process->paras;
+ blocks = (para + paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT;
blocks_change = blocks - old_blocks;
if (process_avail < blocks_change)
return false;
&process->core_item,
blocks,
#ifndef INDIRECT_CORE
- POOL_ALLOC_MODE_MOVEABLE |
- POOL_ALLOC_MODE_REALLOC
+ dir | (POOL_ALLOC_MODE_MOVEABLE | POOL_ALLOC_MODE_REALLOC)
#else /* INDIRECT_CORE */
- POOL_ALLOC_MODE_REALLOC
+ dir | POOL_ALLOC_MODE_REALLOC
#endif /* INDIRECT_CORE */
)
#ifndef INDIRECT_CORE
#endif /* INDIRECT_CORE */
// track total allocation
+ if (dir)
+ process->para = (blocks << BLOCK_PARAS_SHIFT) - para - paras;
process->paras = paras;
process_avail -= blocks_change;
return true;
}
void process_run(struct process *process) {
- int blocks, process_core_blocks, process_swap_blocks;
+ int blocks, runner_core_blocks, runner_swap_blocks;
int swap_base, core_base;
int paras;
#ifndef INDIRECT_CORE
// loop entry code for case of fully in swap
if (process != victim) {
// fully in swap, only the swap item is meaningful
- process_swap_blocks =
+ runner_swap_blocks =
process->swap_item.limit - process->swap_item.base;
// free up as much core as we can
#ifndef INDIRECT_CORE
- do_swap_out(process_swap_blocks - core_table.avail);
+ do_swap_out(runner_swap_blocks - core_table.avail);
blocks = core_table.avail;
#else /* INDIRECT_CORE */
- do_swap_out(process_swap_blocks - core_block_pool.avail);
+ do_swap_out(runner_swap_blocks - core_block_pool.avail);
blocks = core_block_pool.avail;
#endif /* INDIRECT_CORE */
- if (blocks > process_swap_blocks)
- blocks = process_swap_blocks;
+ if (blocks > runner_swap_blocks)
+ blocks = runner_swap_blocks;
// add to core pool
- process_core_blocks = 0;
+ runner = process;
+ runner_core_blocks = 0;
#ifndef INDIRECT_CORE
rassert(
pool_alloc(
}
// victim, take over the dedicated pool items
- process_core_blocks =
+ runner = victim;
+ runner_core_blocks =
#ifndef INDIRECT_CORE
victim->core_item.limit - victim->core_item.base;
#else /* INDIRECT_CORE */
victim->core_item.limit - victim->core_item.base - victim_swap_blocks;
#endif /* INDIRECT_CORE */
- process_swap_blocks = victim_swap_blocks;
+ runner_swap_blocks = victim_swap_blocks;
victim = NULL;
// loop for case of partially in core, partially in swap
do {
// free up as much core as we can
#ifndef INDIRECT_CORE
- do_swap_out(process_swap_blocks - core_table.avail);
+ do_swap_out(runner_swap_blocks - core_table.avail);
blocks = core_table.avail;
#else /* INDIRECT_CORE */
- do_swap_out(process_swap_blocks - core_block_pool.avail);
+ do_swap_out(runner_swap_blocks - core_block_pool.avail);
blocks = core_block_pool.avail;
#endif /* INDIRECT_CORE */
- if (blocks > process_swap_blocks)
- blocks = process_swap_blocks;
+ if (blocks > runner_swap_blocks)
+ blocks = runner_swap_blocks;
// increase core allocation
#ifndef INDIRECT_CORE
pool_alloc(
&core_table,
&process->core_item,
- process_core_blocks + blocks,
+ runner_core_blocks + blocks,
POOL_ALLOC_MODE_MOVEABLE |
POOL_ALLOC_MODE_REALLOC
)
loop_entry_full:
// calculate transfer parameters
- swap_base = process->swap_item.limit - process_swap_blocks;
+ swap_base = process->swap_item.limit - runner_swap_blocks;
#ifndef INDIRECT_CORE
core_base = process->core_item.limit - blocks;
#else /* INDIRECT_CORE */
- core_base = process->core_item.limit - process_swap_blocks;
+ core_base = process->core_item.limit - runner_swap_blocks;
#endif /* INDIRECT_CORE */
- process_core_blocks += blocks;
- process_swap_blocks -= blocks;
+ runner_core_blocks += blocks;
+ runner_swap_blocks -= blocks;
paras = blocks << BLOCK_PARAS_SHIFT;
// transfer data to core
block_pool_free(&swap_block_pool, swap_table_mem + swap_base, blocks);
#endif /* INDIRECT_SWAP */
#endif /* INDIRECT_CORE */
- } while (process_swap_blocks);
+ } while (runner_swap_blocks);
}
+ runner = NULL;
// insert at head of LRU list
process->lru_item.prev = &lru_head;
process_avail += (process->paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT;
process->paras = -1;
}
+
+// improve this later
+void process_get_state(struct process *process, struct process_state *state) {
+ if (process->lru_item.prev != NULL) { // fully in core
+ assert(process != runner);
+ assert(process != victim);
+ state->core_base = process->core_item.base;
+ state->core_blocks = process->core_item.limit - process->core_item.base;
+ state->core_para = process->para;
+ state->core_paras = process->paras;
+ state->swap_base = -1;
+ state->swap_blocks = 0;
+ state->swap_para = 0;
+ state->swap_paras = 0;
+ }
+ else {
+ if (process == runner) { // partially in core, partially in swap
+ assert(process != victim);
+ state->core_base = process->core_item.base;
+ state->core_blocks =
+#ifndef INDIRECT_CORE
+ process->core_item.limit - process->core_item.base;
+#else /* INDIRECT_CORE */
+ process->core_item.limit -
+ process->core_item.base -
+ runner_swap_blocks;
+#endif /* INDIRECT_CORE */
+ state->core_para = process->para;
+ state->core_paras =
+ (state->core_blocks << BLOCK_PARAS_SHIFT) - process->para;
+ state->swap_base = process->swap_item.limit - runner_swap_blocks;
+ state->swap_blocks = runner_swap_blocks;
+ state->swap_para = 0;
+ state->swap_paras = process->paras - state->core_paras;
+ }
+ else if (process == victim) { // partially in core, partially in swap
+ state->core_base = process->core_item.base;
+ state->core_blocks =
+#ifndef INDIRECT_CORE
+ process->core_item.limit - process->core_item.base;
+#else /* INDIRECT_CORE */
+ process->core_item.limit -
+ process->core_item.base -
+ victim_swap_blocks;
+#endif /* INDIRECT_CORE */
+ state->core_para = process->para;
+ state->core_paras =
+ (state->core_blocks << BLOCK_PARAS_SHIFT) - process->para;
+ state->swap_base = process->swap_item.limit - victim_swap_blocks;
+ state->swap_blocks = victim_swap_blocks;
+ state->swap_para = 0;
+ state->swap_paras = process->paras - state->core_paras;
+ }
+ else { // fully in swap
+ state->core_base = -1;
+ state->core_blocks = 0;
+ state->core_para = 0;
+ state->core_paras = 0;
+ state->swap_base = process->swap_item.base;
+ state->swap_blocks = process->swap_item.limit - process->swap_item.base;
+ state->swap_para = process->para;
+ state->swap_paras = process->paras;
+ }
+ }
+}
struct lru_item *next;
};
-extern struct process {
+struct process {
struct lru_item lru_item; // must be first
struct pool_item core_item;
struct pool_item swap_item;
+ int para; // wasted space in first block due to prior use of expand-down
int paras; // brk level
-} *processes;
-int n_processes;
+};
+
+// improve this later
+struct process_state {
+ int core_base;
+ int core_blocks;
+ int core_para;
+ int core_paras;
+ int swap_base;
+ int swap_blocks;
+ int swap_para;
+ int swap_paras;
+};
+
+extern struct process *processes;
+extern int n_processes;
extern int process_avail;
extern struct lru_item lru_head;
+extern struct process *runner;
+extern int runner_swap_blocks;
+
extern struct process *victim;
extern int victim_swap_blocks;
void process_init(int n, int spare);
-bool process_alloc(struct process *process, int paras);
-bool process_realloc(struct process *process, int paras);
+bool process_alloc(struct process *process, int para, int paras);
+bool process_realloc(struct process *process, int paras, bool dir);
void process_run(struct process *process);
void process_free(struct process *process);
-
+void process_get_state(struct process *process, struct process_state *state);
+
// abstract
void core_to_swap_copy(int src_base, int dest_base, int paras);
void swap_to_core_copy(int src_base, int dest_base, int paras);
#define PROCESS_TEST_TYPE_ALLOC 0
#define PROCESS_TEST_TYPE_REALLOC 1
-#define PROCESS_TEST_TYPE_RUN 2
-#define PROCESS_TEST_TYPE_FREE 3
+#define PROCESS_TEST_TYPE_REALLOC_BASE 2
+#define PROCESS_TEST_TYPE_RUN 3
+#define PROCESS_TEST_TYPE_FREE 4
struct process_test {
int type;
int process;
+ int old_para; // for checking only
int old_paras; // for checking only
int old_blocks; // for checking only
+ int para;
int paras;
int blocks; // for checking only
bool success;
return (int)((long)rand() * n / (RAND_MAX + 1L));
}
+struct process {
+ int para;
+ int paras;
+};
+
int main(int argc, char **argv) {
if (argc < 5) {
- printf("usage: %s n_processes pool_blocks n_events process_blocks [seed]\n", argv[0]);
+ printf("usage: %s n_processes pool_blocks n_events process_blocks [do_para [do_base [seed]]]\n", argv[0]);
exit(EXIT_FAILURE);
}
int n_processes = atoi(argv[1]);
int pool_blocks = atoi(argv[2]);
int n_events = atoi(argv[3]);
int process_blocks = atoi(argv[4]);
- int seed = argc >= 6 ? atoi(argv[5]) : 1;
+ bool do_para = argc >= 6 ? strcmp(argv[5], "false") != 0 : false;
+ bool do_base = argc >= 7 ? strcmp(argv[6], "false") != 0 : false;
+ int seed = argc >= 8 ? atoi(argv[7]) : 1;
int process_paras = process_blocks << BLOCK_PARAS_SHIFT;
- int *processes = malloc(n_processes * sizeof(int));
+ struct process *processes = malloc(n_processes * sizeof(struct process));
rassert(processes);
- memset(processes, -1, n_processes * sizeof(int));
+ memset(processes, -1, n_processes * sizeof(struct process));
srand(seed);
int pool_used = 0;
#endif
test.process = rand_int(n_processes);
- test.old_paras = processes[test.process];
+ test.old_para = processes[test.process].para;
+ test.old_paras = processes[test.process].paras;
if (test.old_paras == -1) {
test.old_blocks = -1;
+ test.para = do_para ? rand_int(BLOCK_PARAS) : 0;
test.paras = rand_int(process_paras + 1);
- test.blocks = (test.paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT;
+ test.blocks =
+ (test.para + test.paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT;
test.success = pool_used + test.blocks <= pool_blocks;
#ifdef __FUZIX__
write(1, &test, sizeof(test));
#else
printf(
- "alloc %d %d %d %s\n",
+ "alloc %d %d %d %d %s\n",
test.process,
+ test.para,
test.paras,
test.blocks,
test.success ? "true" : "false"
#endif
if (test.success) {
- processes[test.process] = test.paras;
+ processes[test.process].para = test.para;
+ processes[test.process].paras = test.paras;
pool_used += test.blocks;
}
}
else {
- test.old_blocks =
- (test.old_paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT;
+ test.old_blocks = (
+ test.old_para +
+ test.old_paras +
+ (BLOCK_PARAS - 1)
+ ) >> BLOCK_PARAS_SHIFT;
if (rand_int(64)) {
#ifdef __FUZIX__
test.type = PROCESS_TEST_TYPE_RUN;
#endif
if (rand_int(8) == 0) {
+ bool base = do_base && rand_int(3) == 0;
+
+ test.para = test.old_para;
+ if (base)
+ test.para =
+ (test.old_blocks << BLOCK_PARAS_SHIFT) -
+ test.para -
+ test.old_paras;
+
test.paras =
rand_int(process_paras + 1);
- test.blocks =
- (test.paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT;
+ test.blocks = (
+ test.para +
+ test.paras +
+ (BLOCK_PARAS - 1)
+ ) >> BLOCK_PARAS_SHIFT;
test.success =
pool_used + test.blocks - test.old_blocks <= pool_blocks;
+ if (base)
+ test.para =
+ (test.blocks << BLOCK_PARAS_SHIFT) -
+ test.para -
+ test.paras;
+
#ifdef __FUZIX__
- test.type = PROCESS_TEST_TYPE_REALLOC;
+ test.type =
+ base ?
+ PROCESS_TEST_TYPE_REALLOC_BASE :
+ PROCESS_TEST_TYPE_REALLOC;
write(1, &test, sizeof(test));
#else
printf(
- "realloc %d %d %d %d %d %s\n",
+ "realloc%s %d %d %d %d %d %d %d %s\n",
+ base ? "_base" : "",
test.process,
+ test.old_para,
test.old_paras,
test.old_blocks,
+ test.para,
test.paras,
test.blocks,
test.success ? "true" : "false"
#endif
if (test.success) {
- processes[test.process] = test.paras;
+ processes[test.process].para = test.para;
+ processes[test.process].paras = test.paras;
pool_used += test.blocks - test.old_blocks;
}
}
write(1, &test, sizeof(test));
#else
printf(
- "free %d %d %d\n",
+ "free %d %d %d %d\n",
test.process,
+ test.old_para,
test.old_paras,
test.old_blocks
);
#endif
- processes[test.process] = -1;
+ //processes[test.process].para = -1;
+ processes[test.process].paras = -1;
pool_used -= test.old_blocks;
}
}
void core_copy(int src_base, int dest_base, int paras) {
int i;
- printf("core_copy %d(%d) %d(%d) %d(%d)\n", src_base, src_base >> BLOCK_PARAS_SHIFT, dest_base, dest_base >> BLOCK_PARAS_SHIFT, paras, (paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT);
+ //printf("core_copy %d(%d) %d(%d) %d(%d)\n", src_base, src_base >> BLOCK_PARAS_SHIFT, dest_base, dest_base >> BLOCK_PARAS_SHIFT, paras, (paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT);
for (i = 0; i < paras; ++i) {
core_block_mem[dest_base + i] = core_block_mem[src_base + i];
core_block_mem[src_base + i] = 0xaaaaaaaa;
void core_copy_up(int src_limit, int dest_limit, int paras) {
int i;
- printf("core_copy_up %d(%d) %d(%d) %d(%d)\n", src_limit, src_limit >> BLOCK_PARAS_SHIFT, dest_limit, dest_limit >> BLOCK_PARAS_SHIFT, paras, (paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT);
+ //printf("core_copy_up %d(%d) %d(%d) %d(%d)\n", src_limit, src_limit >> BLOCK_PARAS_SHIFT, dest_limit, dest_limit >> BLOCK_PARAS_SHIFT, paras, (paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT);
paras = -paras;
for (i = -1; i >= paras; --i) {
core_block_mem[dest_limit + i] = core_block_mem[src_limit + i];
char buf[256];
#endif
bool result;
- int old_paras, old_blocks;
- int swap_base, swap_blocks;
- int swap_paras;
- int core_base, core_blocks;
- int core_paras;
+ int old_para, old_paras, old_blocks;
+ int new_para, new_paras, new_blocks;
+ struct process_state state;
if (argc < 5) {
printf(
test.type = PROCESS_TEST_TYPE_ALLOC;
rassert(
scanf(
- "%d %d %d %s",
+ "%d %d %d %d %s",
&test.process,
+ &test.para,
&test.paras,
&test.blocks,
buf
- ) == 4
+ ) == 5
);
rassert(test.process >= 0 && test.process < n_processes);
+ rassert(test.para >= 0);
rassert(test.paras >= 0);
rassert(test.blocks >= 0);
if (strcmp(buf, "false") == 0)
test.type = PROCESS_TEST_TYPE_REALLOC;
rassert(
scanf(
- "%d %d %d %d %d %s",
+ "%d %d %d %d %d %d %d %s",
+ &test.process,
+ &test.old_para,
+ &test.old_paras,
+ &test.old_blocks,
+ &test.para,
+ &test.paras,
+ &test.blocks,
+ buf
+ ) == 8
+ );
+ rassert(test.process >= 0 && test.process < n_processes);
+ rassert(test.old_para >= 0);
+ rassert(test.old_paras >= 0);
+ rassert(test.old_blocks >= 0);
+ rassert(test.para >= 0);
+ rassert(test.paras >= 0);
+ rassert(test.blocks >= 0);
+ if (strcmp(buf, "false") == 0)
+ test.success = false;
+ else if (strcmp(buf, "true") == 0)
+ test.success = true;
+ else
+ rassert(false);
+ }
+ else if (strcmp(buf, "realloc_base") == 0) {
+ test.type = PROCESS_TEST_TYPE_REALLOC_BASE;
+ rassert(
+ scanf(
+ "%d %d %d %d %d %d %d %s",
&test.process,
+ &test.old_para,
&test.old_paras,
&test.old_blocks,
+ &test.para,
&test.paras,
&test.blocks,
buf
- ) == 6
+ ) == 8
);
rassert(test.process >= 0 && test.process < n_processes);
+ rassert(test.old_para >= 0);
rassert(test.old_paras >= 0);
rassert(test.old_blocks >= 0);
+ rassert(test.para >= 0);
rassert(test.paras >= 0);
rassert(test.blocks >= 0);
if (strcmp(buf, "false") == 0)
test.type = PROCESS_TEST_TYPE_FREE;
rassert(
scanf(
- "%d %d %d",
+ "%d %d %d %d",
&test.process,
+ &test.old_para,
&test.old_paras,
&test.old_blocks
- ) == 3
+ ) == 4
);
rassert(test.process >= 0 && test.process < n_processes);
+ rassert(test.old_para >= 0);
rassert(test.old_paras >= 0);
rassert(test.old_blocks >= 0);
}
switch (test.type) {
case PROCESS_TEST_TYPE_ALLOC:
printf(
- "alloc %d %d %d %s\n",
+ "alloc %d %d %d %d %s\n",
test.process,
+ test.para,
test.paras,
test.blocks,
test.success ? "true" : "false"
);
rassert(processes[test.process].paras == -1);
- result = process_alloc(processes + test.process, test.paras);
+ result = process_alloc(
+ processes + test.process,
+ test.para,
+ test.paras
+ );
printf(
"... %s\n",
result == test.success ?
}
else {
printf("new core [%d,%d) swap reservation [%d, %d)\n", processes[test.process].core_item.base, processes[test.process].core_item.limit, processes[test.process].swap_item.base, processes[test.process].swap_item.limit);
+ rassert(processes[test.process].para == test.para);
+ rassert(processes[test.process].paras == test.paras);
rassert(
processes[test.process].swap_item.limit -
processes[test.process].swap_item.base ==
);
core_hash_init(
test.process,
- processes[test.process].core_item.base << BLOCK_PARAS_SHIFT,
+ (processes[test.process].core_item.base << BLOCK_PARAS_SHIFT) +
+ test.para,
test.paras,
0
);
break;
case PROCESS_TEST_TYPE_REALLOC:
printf(
- "realloc %d %d %d %d %d %s\n",
+ "realloc %d %d %d %d %d %d %d %s\n",
test.process,
+ test.old_para,
test.old_paras,
test.old_blocks,
+ test.para,
test.paras,
test.blocks,
test.success ? "true" : "false"
printf("... not allocated, ignore\n");
else {
printf("old core [%d,%d) swap reservation [%d,%d)\n", processes[test.process].core_item.base, processes[test.process].core_item.limit, processes[test.process].swap_item.base, processes[test.process].swap_item.limit);
+ old_para = processes[test.process].para;
+ if (old_para != test.old_para) {
+ printf(
+ "... old para %d, should be %d\n",
+ old_para,
+ test.old_para
+ );
+ }
old_paras = processes[test.process].paras;
if (old_paras != test.old_paras) {
printf(
old_paras,
test.old_paras
);
- rassert(old_paras <= test.old_paras);
}
old_blocks =
processes[test.process].swap_item.limit -
old_blocks,
test.old_blocks
);
- rassert(old_blocks <= test.old_blocks);
}
core_hash_verify(
test.process,
(processes[test.process].core_item.base << BLOCK_PARAS_SHIFT) +
+ old_para +
test.paras,
old_paras - test.paras,
test.paras
);
- result = process_realloc(processes + test.process, test.paras);
+ result = process_realloc(
+ processes + test.process,
+ test.paras,
+ false
+ );
printf(
"... %s\n",
result == test.success ?
if (!test.success) {
printf("... undo\n");
rassert(
- process_realloc(processes + test.process, old_paras)
+ process_realloc(
+ processes + test.process,
+ old_paras,
+ false
+ )
+ );
+ rassert(processes[test.process].para == old_para);
+ rassert(processes[test.process].paras == old_paras);
+ rassert(
+ processes[test.process].swap_item.limit -
+ processes[test.process].swap_item.base ==
+ old_blocks
);
}
else {
printf("new core [%d,%d) swap reservation [%d, %d)\n", processes[test.process].core_item.base, processes[test.process].core_item.limit, processes[test.process].swap_item.base, processes[test.process].swap_item.limit);
+ new_para = processes[test.process].para;
+ if (new_para != test.para) {
+ printf(
+ "... new para %d, should be %d\n",
+ new_para,
+ test.para
+ );
+ }
+ new_paras = processes[test.process].paras;
+ if (new_paras != test.paras) {
+ printf(
+ "... new paras %d, should be %d\n",
+ new_paras,
+ test.paras
+ );
+ }
+ new_blocks =
+ processes[test.process].swap_item.limit -
+ processes[test.process].swap_item.base;
+ if (new_blocks != test.blocks) {
+ printf(
+ "... new blocks %d, should be %d\n",
+ new_blocks,
+ test.blocks
+ );
+ }
+ core_hash_init(
+ test.process,
+ (processes[test.process].core_item.base << BLOCK_PARAS_SHIFT) +
+ new_para +
+ old_paras,
+ new_paras - old_paras,
+ old_paras
+ );
+ }
+ }
+ }
+ break;
+ case PROCESS_TEST_TYPE_REALLOC_BASE:
+ printf(
+ "realloc_base %d %d %d %d %d %d %d %s\n",
+ test.process,
+ test.old_para,
+ test.old_paras,
+ test.old_blocks,
+ test.para,
+ test.paras,
+ test.blocks,
+ test.success ? "true" : "false"
+ );
+ if (processes[test.process].paras == -1)
+ printf("... not allocated, ignore\n");
+ else {
+ printf("old core [%d,%d) swap reservation [%d,%d)\n", processes[test.process].core_item.base, processes[test.process].core_item.limit, processes[test.process].swap_item.base, processes[test.process].swap_item.limit);
+ old_para = processes[test.process].para;
+ if (old_para != test.old_para) {
+ printf(
+ "... old para %d, should be %d\n",
+ old_para,
+ test.old_para
+ );
+ }
+ old_paras = processes[test.process].paras;
+ if (old_paras != test.old_paras) {
+ printf(
+ "... old paras %d, should be %d\n",
+ old_paras,
+ test.old_paras
+ );
+ }
+ old_blocks =
+ processes[test.process].swap_item.limit -
+ processes[test.process].swap_item.base;
+ if (old_blocks != test.old_blocks) {
+ printf(
+ "... old blocks %d, should be %d\n",
+ old_blocks,
+ test.old_blocks
+ );
+ }
+ core_hash_verify(
+ test.process,
+ (processes[test.process].core_item.base << BLOCK_PARAS_SHIFT) +
+ old_para,
+ old_paras - test.paras,
+ 0
+ );
+ result = process_realloc(
+ processes + test.process,
+ test.paras,
+ true
+ );
+ printf(
+ "... %s\n",
+ result == test.success ?
+ "ok" :
+ result ? "succeeded, should fail" : "failed, should succeed"
+ );
+ if (result) {
+ if (!test.success) {
+ printf("... undo\n");
+ rassert(
+ process_realloc(
+ processes + test.process,
+ old_paras,
+ true
+ )
+ );
+ rassert(processes[test.process].para == old_para);
+ rassert(processes[test.process].paras == old_paras);
rassert(
processes[test.process].swap_item.limit -
processes[test.process].swap_item.base ==
- test.blocks
+ old_blocks
);
+ }
+ else {
+ printf("new core [%d,%d) swap reservation [%d,%d)\n", processes[test.process].core_item.base, processes[test.process].core_item.limit, processes[test.process].swap_item.base, processes[test.process].swap_item.limit);
+ new_para = processes[test.process].para;
+ if (new_para != test.para) {
+ printf(
+ "... new para %d, should be %d\n",
+ new_para,
+ test.para
+ );
+ }
+ new_paras = processes[test.process].paras;
+ if (new_paras != test.paras) {
+ printf(
+ "... new paras %d, should be %d\n",
+ new_paras,
+ test.paras
+ );
+ }
+ new_blocks =
+ processes[test.process].swap_item.limit -
+ processes[test.process].swap_item.base;
+ if (new_blocks != test.blocks) {
+ printf(
+ "... new blocks %d, should be %d\n",
+ new_blocks,
+ test.blocks
+ );
+ }
+ if (new_paras >= old_paras)
+ core_hash_verify(
+ test.process,
+ (processes[test.process].core_item.base << BLOCK_PARAS_SHIFT) +
+ new_para +
+ new_paras -
+ old_paras,
+ old_paras,
+ 0
+ );
+ else
+ core_hash_verify(
+ test.process,
+ (processes[test.process].core_item.base << BLOCK_PARAS_SHIFT) +
+ new_para,
+ new_paras,
+ old_paras - new_paras
+ );
core_hash_init(
test.process,
(processes[test.process].core_item.base << BLOCK_PARAS_SHIFT) +
- old_paras,
- test.paras - old_paras,
- old_paras
+ new_para,
+ new_paras,
+ 0
);
}
}
break;
case PROCESS_TEST_TYPE_FREE:
printf(
- "free %d %d %d\n",
+ "free %d %d %d %d\n",
test.process,
+ test.old_para,
test.old_paras,
test.old_blocks
);
if (processes[test.process].paras == -1)
printf("... not allocated, ignore\n");
else {
+ old_para = processes[test.process].para;
+ if (old_para != test.old_para) {
+ printf(
+ "... old para %d, should be %d\n",
+ old_para,
+ test.old_para
+ );
+ }
old_paras = processes[test.process].paras;
if (old_paras != test.old_paras) {
printf(
old_paras,
test.old_paras
);
- rassert(old_paras <= test.old_paras);
}
old_blocks =
processes[test.process].swap_item.limit -
old_blocks,
test.old_blocks
);
- rassert(old_blocks <= test.old_blocks);
- }
- if (processes[test.process].lru_item.prev != NULL) { // fully in core
- assert(processes + test.process != victim);
- core_base = processes[test.process].core_item.base;
- core_blocks = processes[test.process].core_item.limit - core_base;
- core_paras = processes[test.process].paras;
- swap_base = -1;
- swap_blocks = 0;
- swap_paras = 0;
- }
- else {
- if (processes + test.process == victim) { // victim
- core_base = victim->core_item.base;
-#ifndef INDIRECT_CORE
- core_blocks = victim->core_item.limit - core_base;
-#else /* INDIRECT_CORE */
- core_blocks = victim->core_item.limit - core_base - victim_swap_blocks;
-#endif /* INDIRECT_CORE */
- core_paras = core_blocks << BLOCK_PARAS_SHIFT;
- swap_base = victim->swap_item.limit - victim_swap_blocks;
- swap_blocks = victim_swap_blocks;
- swap_paras = victim->paras - core_paras;
- }
- else { // fully in swap
- core_base = -1;
- core_blocks = 0;
- core_paras = 0;
- swap_base = processes[test.process].swap_item.base;
- swap_blocks = processes[test.process].swap_item.limit - swap_base;
- swap_paras = processes[test.process].paras;
- }
}
- printf("old core [%d,%d) swap occupation [%d,%d)\n", core_base, core_base + core_blocks, swap_base, swap_base + swap_blocks);
- fflush(stdout);
+ process_get_state(processes + test.process, &state);
+ printf("old core [%d,%d) swap occupation [%d,%d)\n", state.core_base, state.core_base + state.core_blocks, state.swap_base, state.swap_base + state.swap_blocks);
core_hash_verify(
test.process,
- core_base << BLOCK_PARAS_SHIFT,
- core_paras,
+ (state.core_base << BLOCK_PARAS_SHIFT) + state.core_para,
+ state.core_paras,
0
);
swap_hash_verify(
test.process,
- swap_base << BLOCK_PARAS_SHIFT,
- swap_paras,
- core_paras
+ (state.swap_base << BLOCK_PARAS_SHIFT) + state.swap_para,
+ state.swap_paras,
+ state.core_paras
);
process_free(processes + test.process);
processes[test.process].paras = -1;
if (processes[i].paras == -1)
printf("process %d: not allocated\n", i);
else {
- if (processes[i].lru_item.prev != NULL) { // fully in core
- assert(processes + i != victim);
- core_base = processes[i].core_item.base;
- core_blocks = processes[i].core_item.limit - core_base;
- core_paras = processes[i].paras;
- swap_base = -1;
- swap_blocks = 0;
- swap_paras = 0;
- }
- else {
- if (processes + i == victim) { // victim
- core_base = victim->core_item.base;
-#ifndef INDIRECT_CORE
- core_blocks = victim->core_item.limit - core_base;
-#else /* INDIRECT_CORE */
- core_blocks = victim->core_item.limit - core_base - victim_swap_blocks;
-#endif /* INDIRECT_CORE */
- core_paras = core_blocks << BLOCK_PARAS_SHIFT;
- swap_base = victim->swap_item.limit - victim_swap_blocks;
- swap_blocks = victim_swap_blocks;
- swap_paras = victim->paras - core_paras;
- }
- else { // fully in swap
- core_base = -1;
- core_blocks = 0;
- core_paras = 0;
- swap_base = processes[i].swap_item.base;
- swap_blocks = processes[i].swap_item.limit - swap_base;
- swap_paras = processes[i].paras;
- }
- }
- rassert(
- core_blocks + swap_blocks ==
- (processes[i].paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT
- );
+ process_get_state(processes + i, &state);
printf(
"process %d: core [%d,%d) swap occupation [%d,%d)\n",
i,
- core_base,
- core_base + core_blocks,
- swap_base,
- swap_base + swap_blocks
+ state.core_base,
+ state.core_base + state.core_blocks,
+ state.swap_base,
+ state.swap_base + state.swap_blocks
);
core_hash_verify(
i,
- core_base << BLOCK_PARAS_SHIFT,
- core_paras,
+ (state.core_base << BLOCK_PARAS_SHIFT) + state.core_para,
+ state.core_paras,
0
);
#ifdef INDIRECT_CORE
block_pool_free(
&core_block_pool,
- core_table_mem + core_base,
- core_blocks
+ core_table_mem + state.core_base,
+ state.core_blocks
);
#endif /* INDIRECT_CORE */
swap_hash_verify(
i,
- swap_base << BLOCK_PARAS_SHIFT,
- swap_paras,
- core_paras
+ (state.swap_base << BLOCK_PARAS_SHIFT) + state.swap_para,
+ state.swap_paras,
+ state.core_paras
);
#ifdef INDIRECT_SWAP
block_pool_free(
&swap_block_pool,
- swap_table_mem + swap_base,
- swap_blocks
+ swap_table_mem + state.swap_base,
+ state.swap_blocks
);
#endif /* INDIRECT_SWAP */
}