int base, blocks;
#ifndef INDIRECT_CORE
struct process *process;
- struct process_state state;
+ struct process_calc calc;
+ int in_core_para, para_base;
#else /* INDIRECT_CORE */
int i;
#endif /* INDIRECT_CORE */
process = (struct process *)(
(char *)item - offsetof(struct process, core_item)
);
- process_get_state(process, &state);
+ process_calc(process, &calc);
+ in_core_para = calc.in_core_block << BLOCK_PARAS_SHIFT;
+ if (in_core_para < process->para_base)
+ in_core_para = process->para_base;
+ else if (in_core_para > process->para_limit)
+ in_core_para = process->para_limit;
// copy valid part by abstract routine
+ para_base = (calc.core_origin << BLOCK_PARAS_SHIFT) + process->para_base;
core_copy(
- state.core_para,
- state.core_para + ((new_base - base) << BLOCK_PARAS_SHIFT),
- state.core_paras
+ para_base,
+ para_base + ((new_base - base) << BLOCK_PARAS_SHIFT),
+ in_core_para - process->para_base
);
#endif
#else /* INDIRECT_CORE */
int limit, blocks;
#ifndef INDIRECT_CORE
struct process *process;
- struct process_state state;
- int para;
+ struct process_calc calc;
+ int in_core_para, para_limit;
#else /* INDIRECT_CORE */
int i;
#endif /* INDIRECT_CORE */
process = (struct process *)(
(char *)item - offsetof(struct process, core_item)
);
- process_get_state(process, &state);
+ process_calc(process, &calc);
+ in_core_para = calc.in_core_block << BLOCK_PARAS_SHIFT;
+ if (in_core_para < process->para_base)
+ in_core_para = process->para_base;
+ else if (in_core_para > process->para_limit)
+ in_core_para = process->para_limit;
// copy valid part by abstract routine
- para = state.core_para + state.core_paras;
+ para_limit = (calc.core_origin << BLOCK_PARAS_SHIFT) + in_core_para;
core_copy_up(
- para,
- para + ((new_limit - limit) << BLOCK_PARAS_SHIFT),
- state.core_paras
+ para_limit,
+ para_limit + ((new_limit - limit) << BLOCK_PARAS_SHIFT),
+ in_core_para - process->para_base
);
#endif
#else /* INDIRECT_CORE */
#!/bin/sh
echo "generate test script"
-./process_test_gen 16 248 4096 32 true true >process_test.txt
+./process_test_gen 16 248 4096 -16 16 true >process_test.txt
echo "run test script"
./process_test_run 16 64 192 8 384 384 <process_test.txt
#!/bin/sh
echo "generate test script"
-./process_test_gen 16 248 4096 32 true true >process_test.txt
+./process_test_gen 16 248 4096 -16 16 true >process_test.txt
echo "run test script"
./process_test_run 16 64 192 8 384 384 <process_test.txt
#!/bin/sh
echo "generate test script"
-./process_test_gen 16 248 4096 32 true true >process_test.txt
+./process_test_gen 16 248 4096 -16 16 true >process_test.txt
echo "run test script"
./process_test_run 16 64 192 8 384 <process_test.txt
#!/bin/sh
echo "generate test script"
-./process_test_gen 16 248 4096 32 true true >process_test.txt
+./process_test_gen 16 248 4096 -16 16 true >process_test.txt
echo "run test script"
./process_test_run 16 64 192 8 384 <process_test.txt
#!/bin/sh
echo "generate test script"
-./process_test_gen 16 248 4096 32 true true >process_test.txt
+./process_test_gen 16 248 4096 -16 16 true >process_test.txt
echo "run test script"
./process_test_run 16 64 192 8 384 384 <process_test.txt
#ifndef INDIRECT_CORE
block = process->core_item.limit - process->core_item.base;
#else /* INDIRECT_CORE */
- block = process->core_blocks;
+ block = process->in_core_blocks;
#endif /* INDIRECT_CORE */
#ifndef INDIRECT_SWAP
blocks = swap_out < block ? swap_out : block;
// adjust swap pointer
block -= blocks;
#ifdef INDIRECT_CORE
- process->core_blocks = block;
+ process->in_core_blocks = block;
#endif
// transfer data to swap
return true;
}
-bool process_alloc(struct process *process, int para, int paras) {
+static int calc_blocks(int para_base, int para_limit) {
+ return
+ ((para_limit + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT) -
+ (para_base >> BLOCK_PARAS_SHIFT);
+}
+
+bool process_alloc(struct process *process, int para_base, int para_limit) {
int blocks;
// must not be already allocated
assert((process->flags & PROCESS_FLAGS_ACTIVE) == 0);
// check blocks
- blocks = (para + paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT;
+ blocks = calc_blocks(para_base, para_limit);
if (
process_avail < blocks ||
- !pool_alloc(
- &swap_table,
- &process->swap_item,
- blocks,
- 0
- )
+ !pool_alloc(&swap_table, &process->swap_item, blocks, 0)
)
return false;
);
#else /* INDIRECT_CORE */
// allocate core and possible swap
- if (
- !pool_alloc(
- &core_table,
- &process->core_item,
- blocks,
- 0
- )
- ) {
+ if (!pool_alloc(&core_table, &process->core_item, blocks, 0)) {
pool_free(&swap_table, &process->swap_item);
return false;
}
#else /* INDIRECT_CORE */
process->flags = PROCESS_FLAGS_ACTIVE;
#endif /* INDIRECT_CORE */
- process->para = para;
- process->paras = paras;
+ process->para_base = para_base;
+ process->para_limit = para_limit;
#ifdef INDIRECT_CORE
- process->core_blocks = blocks;
+ process->in_core_blocks = blocks;
#endif
process_avail -= blocks;
return true;
}
-bool process_realloc(struct process *process, int paras, bool dir) {
- int old_blocks, para, blocks, blocks_change;
+bool process_realloc(struct process *process, int para_base_limit, bool dir) {
+ int old_blocks, blocks, blocks_change;
// must be already allocated
assert(process->flags & PROCESS_FLAGS_ACTIVE);
);
#else
assert(
- process->core_blocks ==
+ process->in_core_blocks ==
process->swap_item.limit - process->swap_item.base
);
#endif /* ! INDIRECT_CORE */
// check blocks
- old_blocks = process->swap_item.limit - process->swap_item.base;
- para = process->para;
- if (dir)
- para = (old_blocks << BLOCK_PARAS_SHIFT) - para - process->paras;
- blocks = (para + paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT;
+ old_blocks = calc_blocks(process->para_base, process->para_limit);
+ blocks =
+ dir ?
+ calc_blocks(para_base_limit, process->para_limit) :
+ calc_blocks(process->para_base, para_base_limit);
blocks_change = blocks - old_blocks;
if (process_avail < blocks_change)
return false;
// this is a bit clunky, we want realloc without copying old contents,
// so we free, try to allocate larger, if that fails, allocate original
pool_free(&swap_table, &process->swap_item);
- if (
- !pool_alloc(
- &swap_table,
- &process->swap_item,
- blocks,
- 0
- )
- ) {
- rassert(
- pool_alloc(
- &swap_table,
- &process->swap_item,
- old_blocks,
- 0
- )
- );
+ if (!pool_alloc(&swap_table, &process->swap_item, blocks, 0)) {
+ rassert(pool_alloc(&swap_table, &process->swap_item, old_blocks, 0));
return false;
}
// free up as much core as we need to
rassert(do_swap_out(blocks_change - core_table.avail));
- // reallocate core and possible swap
+ // reallocate core
rassert(
pool_alloc(
&core_table,
-blocks_change
);
- // reallocate core and possible swap
+ // reallocate core
if (
!pool_alloc(
&core_table,
#endif /* INDIRECT_CORE */
// track total allocation
- if (dir)
- process->para = (blocks << BLOCK_PARAS_SHIFT) - para - paras;
- process->paras = paras;
+ *(dir ? &process->para_base : &process->para_limit) = para_base_limit;
#ifdef INDIRECT_CORE
- process->core_blocks = blocks;
+ process->in_core_blocks = blocks;
#endif
process_avail -= blocks_change;
return true;
process->core_item.limit - process->core_item.base :
0;
#else /* INDIRECT_CORE */
- block = process->core_blocks;
+ block = process->in_core_blocks;
#endif /* INDIRECT_CORE */
for (
swap_in =
// adjust swap pointer
block += blocks;
#ifdef INDIRECT_CORE
- process->core_blocks = block;
+ process->in_core_blocks = block;
#endif /* INDIRECT_CORE */
}
process->core_item.limit - process->core_item.base :
0;
#else /* INDIRECT_CORE */
- block = process->core_blocks;
+ block = process->in_core_blocks;
#endif /* INDIRECT_CORE */
swap_in =
process->swap_item.limit - process->swap_item.base - block;
#ifdef INDIRECT_SWAP
block
#else /* ! INDIRECT_SWAP */
- process->core_blocks
+ process->in_core_blocks
#endif /* ! INDIRECT_SWAP */
);
pool_free(&core_table, &process->core_item);
pool_free(&swap_table, &process->swap_item);
// track total allocation
- process_avail += (process->paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT;
+ process_avail += calc_blocks(process->para_base, process->para_limit);
process->flags = 0;
}
-// ugh. improve this later
-void process_get_state(struct process *process, struct process_state *state) {
- int para;
+void process_calc(struct process *process, struct process_calc *calc) {
+ calc->block_base =
+ process->para_base >> BLOCK_PARAS_SHIFT;
+ calc->block_limit =
+ (process->para_limit + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT;
+#ifdef INDIRECT_CORE
+ assert(
+ process->core_item.limit - process->core_item.base ==
+ calc->block_limit - calc->block_base
+ );
+#endif /* INDIRECT_CORE */
+ // note: following can fail during realloc because swap reallocated first:
+ //assert(
+ // process->swap_item.limit - process->swap_item.base ==
+ // calc->block_limit - calc->block_base
+ //);
#ifndef INDIRECT_CORE
- if (process->flags & PROCESS_FLAGS_CORE_ITEM) {
- state->core_block = process->core_item.base;
- state->core_blocks = process->core_item.limit - process->core_item.base;
- }
- else {
- state->core_block = -1;
- state->core_blocks = 0;
- }
+ calc->core_origin = (
+ process->flags & PROCESS_FLAGS_CORE_ITEM ? process->core_item.base : 0
+ ) - calc->block_base;
#else /* INDIRECT_CORE */
- state->core_block = process->core_item.base;
- state->core_blocks = process->core_blocks;
-#endif /* INDIRECT_CORE */
- state->core_para =
- (state->core_block << BLOCK_PARAS_SHIFT) + process->para;
- state->core_paras =
- (state->core_blocks << BLOCK_PARAS_SHIFT) - process->para;
- if (state->core_paras < 0)
- state->core_paras = 0;
- if (state->core_paras > process->paras)
- state->core_paras = process->paras;
-
- state->swap_block =
- process->swap_item.base + state->core_blocks;
- state->swap_blocks =
- process->swap_item.limit - process->swap_item.base - state->core_blocks;
- para =
- (
- (process->swap_item.limit - process->swap_item.base) <<
- BLOCK_PARAS_SHIFT
- ) - process->para - process->paras;
- //printf("a %d+%d+%d=%d*%d\n", process->para, process->paras, para, process->swap_item.limit - process->swap_item.base, BLOCK_PARAS);
- state->swap_paras =
- (state->swap_blocks << BLOCK_PARAS_SHIFT) - para;
- if (state->swap_paras < 0)
- state->swap_paras = 0;
- if (state->swap_paras > process->paras)
- state->swap_paras = process->paras;
- state->swap_para =
- (state->swap_block << BLOCK_PARAS_SHIFT) +
- (state->swap_blocks << BLOCK_PARAS_SHIFT) -
- para -
- state->swap_paras;
- //printf("b %d+%d+%d=%d*%d\n", state->swap_para, state->swap_paras, para, process->swap_blocks, BLOCK_PARAS);
+ calc->core_origin = process->core_item.base - calc->block_base;
+ assert(calc->core_origin == process->core_item.limit - calc->block_limit);
+#endif
+ // note: following can fail during realloc because swap reallocated first:
+ calc->swap_origin = process->swap_item.base - calc->block_base;
+ //assert(calc->swap_origin == process->swap_item.limit - calc->block_limit);
+
+#ifndef INDIRECT_CORE
+ calc->in_core_block = (
+ process->flags & PROCESS_FLAGS_CORE_ITEM ? process->core_item.limit : 0
+ ) - calc->core_origin;
+ //printf("para [%d,%d) in_core_blocks %d block [%d,%d) core_origin %d swap_origin %d in_core_block %d\n", process->para_base, process->para_limit, process->flags & PROCESS_FLAGS_CORE_ITEM ? process->core_item.limit - process->core_item.base : 0, calc->block_base, calc->block_limit, calc->core_origin, calc->swap_origin, calc->in_core_block);
+#else
+ calc->in_core_block = calc->block_base + process->in_core_blocks;
+ //printf("para [%d,%d) in_core_blocks %d block [%d,%d) core_origin %d swap_origin %d in_core_block %d\n", process->para_base, process->para_limit, process->in_core_blocks, calc->block_base, calc->block_limit, calc->core_origin, calc->swap_origin, calc->in_core_block);
+#endif
}
struct lru_item lru_item;
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
+ int para_base;
+ int para_limit;
#ifdef INDIRECT_CORE
- int core_blocks;
+ int in_core_blocks;
#endif
};
-// improve this later
-struct process_state {
- int core_block;
- int core_blocks;
- int core_para;
- int core_paras;
- int swap_block;
- int swap_blocks;
- int swap_para;
- int swap_paras;
+// derived variables, not stored in process to save space
+struct process_calc {
+ int block_base;
+ int block_limit;
+ int core_origin;
+ int swap_origin;
+ int in_core_block;
};
extern struct process *processes;
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);
+void process_calc(struct process *process, struct process_calc *calc);
// abstract
void swap_read_write(int core_block, int swap_block, int blocks, bool dir);
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
+ int old_para_base;
+ int old_para_limit;
+ int para_base;
+ int para_limit;
bool success;
};
#define PARA_SHIFT 8
#define BLOCK_SHIFT 9
-//#define PAGE_SHIFT 12
#define BLOCK_PARAS_SHIFT (BLOCK_SHIFT - PARA_SHIFT)
#define BLOCK_PARAS (1 << BLOCK_PARAS_SHIFT)
return (int)((long)rand() * n / (RAND_MAX + 1L));
}
+int calc_blocks(int para_base, int para_limit) {
+ return
+ ((para_limit + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT) -
+ (para_base >> BLOCK_PARAS_SHIFT);
+}
+
struct process {
- int para;
- int paras;
+ bool active;
+ int para_base;
+ int para_limit;
};
int main(int argc, char **argv) {
if (argc < 5) {
- printf("usage: %s n_processes pool_blocks n_events process_blocks [do_para [do_base [seed]]]\n", argv[0]);
+ printf("usage: %s n_processes pool_blocks n_events para_base para_limit [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]);
- bool do_para = argc >= 6 ? strcmp(argv[5], "false") != 0 : false;
+ int para_base = atoi(argv[4]);
+ int para_limit = atoi(argv[5]);
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;
+ rassert(para_limit >= para_base);
struct process *processes = malloc(n_processes * sizeof(struct process));
rassert(processes);
- memset(processes, -1, n_processes * sizeof(struct process));
+ memset(processes, 0, n_processes * sizeof(struct process));
srand(seed);
int pool_used = 0;
#endif
test.process = rand_int(n_processes);
- 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.para + test.paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT;
- test.success = pool_used + test.blocks <= pool_blocks;
+ struct process *process = processes + test.process;
+
+ test.old_para_base = process->para_base;
+ test.old_para_limit = process->para_limit;
+ if (!process->active) {
+ test.para_base =
+ (do_base ? rand_int(para_limit - para_base + 1) : 0) + para_base;
+ test.para_limit =
+ rand_int(para_limit - para_base + 1) + para_base;
+ if (test.para_base > test.para_limit) {
+ int i = test.para_base;
+ test.para_base = test.para_limit;
+ test.para_limit = i;
+ }
+ int blocks = calc_blocks(test.para_base, test.para_limit);
+ test.success = pool_used + blocks <= pool_blocks;
#ifdef __FUZIX__
test.type = PROCESS_TEST_TYPE_ALLOC;
write(1, &test, sizeof(test));
#else
printf(
- "alloc %d %d %d %d %s\n",
+ "alloc %d %d %d %s\n",
test.process,
- test.para,
- test.paras,
- test.blocks,
+ test.para_base,
+ test.para_limit,
test.success ? "true" : "false"
);
#endif
if (test.success) {
- processes[test.process].para = test.para;
- processes[test.process].paras = test.paras;
- pool_used += test.blocks;
+ process->active = true;
+ process->para_base = test.para_base;
+ process->para_limit = test.para_limit;
+ pool_used += blocks;
}
}
else {
- test.old_blocks = (
- test.old_para +
- test.old_paras +
- (BLOCK_PARAS - 1)
- ) >> BLOCK_PARAS_SHIFT;
+ int old_blocks = calc_blocks(process->para_base, process->para_limit);
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.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;
+ if (do_base && rand_int(3) == 0) {
+ test.para_base =
+ rand_int(process->para_limit - para_base + 1) +
+ para_base;
+ int blocks = calc_blocks(test.para_base, process->para_limit);
+ test.success = pool_used + blocks - old_blocks <= pool_blocks;
+
+#ifdef __FUZIX__
+ test.type = PROCESS_TEST_TYPE_REALLOC_BASE;
+ write(1, &test, sizeof(test));
+#else
+ printf(
+ "realloc_base %d %d %d %s\n",
+ test.process,
+ test.old_para_base,
+ test.para_base,
+ test.success ? "true" : "false"
+ );
+#endif
+
+ if (test.success) {
+ process->para_base = test.para_base;
+ pool_used += blocks - old_blocks;
+ }
+ }
+ else {
+ test.para_limit =
+ rand_int(para_limit - process->para_base + 1) +
+ process->para_base;
+ int blocks = calc_blocks(process->para_base, test.para_limit);
+ test.success = pool_used + blocks - old_blocks <= pool_blocks;
#ifdef __FUZIX__
- test.type =
- base ?
- PROCESS_TEST_TYPE_REALLOC_BASE :
- PROCESS_TEST_TYPE_REALLOC;
- write(1, &test, sizeof(test));
+ test.type = PROCESS_TEST_TYPE_REALLOC;
+ write(1, &test, sizeof(test));
#else
- printf(
- "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"
- );
+ printf(
+ "realloc %d %d %d %s\n",
+ test.process,
+ test.old_para_limit,
+ test.para_limit,
+ test.success ? "true" : "false"
+ );
#endif
- if (test.success) {
- processes[test.process].para = test.para;
- processes[test.process].paras = test.paras;
- pool_used += test.blocks - test.old_blocks;
+ if (test.success) {
+ process->para_limit = test.para_limit;
+ pool_used += blocks - old_blocks;
+ }
}
}
}
write(1, &test, sizeof(test));
#else
printf(
- "free %d %d %d %d\n",
+ "free %d %d %d\n",
test.process,
- test.old_para,
- test.old_paras,
- test.old_blocks
+ test.old_para_base,
+ test.old_para_limit
);
#endif
- //processes[test.process].para = -1;
- processes[test.process].paras = -1;
- pool_used -= test.old_blocks;
+ process->active = false;
+ pool_used -= old_blocks;
}
}
}
#ifndef __FUZIX__
char buf[256];
#endif
+ struct process *process;
bool result;
- int old_para, old_paras, old_blocks;
- int new_para, new_paras, new_blocks;
- struct process_state state;
+ int old_para_base, old_para_limit;
+ struct process_calc calc;
+ int in_core_para;
if (argc < 5) {
printf(
memset(swap_block_mem, 0xaa, n_swap_blocks * (BLOCK_PARAS * sizeof(int)));
process_init(n_processes, spare);
- for (i = 0; i < n_processes; ++i)
- processes[i].paras = -1;
while (true) {
//printf("avail %d %d(%d) %d(%d)\n", process_avail, CORE_AVAIL, core_table.avail, SWAP_AVAIL, swap_table.avail);
test.type = PROCESS_TEST_TYPE_ALLOC;
rassert(
scanf(
- "%d %d %d %d %s",
+ "%d %d %d %s",
&test.process,
- &test.para,
- &test.paras,
- &test.blocks,
+ &test.para_base,
+ &test.para_limit,
buf
- ) == 5
+ ) == 4
);
rassert(test.process >= 0 && test.process < n_processes);
- rassert(test.para >= 0);
- rassert(test.paras >= 0);
- rassert(test.blocks >= 0);
+ rassert(test.para_limit >= test.para_base);
if (strcmp(buf, "false") == 0)
test.success = false;
else if (strcmp(buf, "true") == 0)
test.type = PROCESS_TEST_TYPE_REALLOC;
rassert(
scanf(
- "%d %d %d %d %d %d %d %s",
+ "%d %d %d %s",
&test.process,
- &test.old_para,
- &test.old_paras,
- &test.old_blocks,
- &test.para,
- &test.paras,
- &test.blocks,
+ &test.old_para_limit,
+ &test.para_limit,
buf
- ) == 8
+ ) == 4
);
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.type = PROCESS_TEST_TYPE_REALLOC_BASE;
rassert(
scanf(
- "%d %d %d %d %d %d %d %s",
+ "%d %d %d %s",
&test.process,
- &test.old_para,
- &test.old_paras,
- &test.old_blocks,
- &test.para,
- &test.paras,
- &test.blocks,
+ &test.old_para_base,
+ &test.para_base,
buf
- ) == 8
+ ) == 4
);
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.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
- ) == 4
+ &test.old_para_base,
+ &test.old_para_limit
+ ) == 3
);
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.old_para_limit >= test.old_para_base);
}
else
rassert(false);
#endif
+ process = processes + test.process;
switch (test.type) {
case PROCESS_TEST_TYPE_ALLOC:
printf(
- "alloc %d %d %d %d %s\n",
+ "alloc %d %d %d %s\n",
test.process,
- test.para,
- test.paras,
- test.blocks,
+ test.para_base,
+ test.para_limit,
test.success ? "true" : "false"
);
- rassert(processes[test.process].paras == -1);
- result = process_alloc(
- processes + test.process,
- test.para,
- test.paras
- );
+ rassert((process->flags & PROCESS_FLAGS_ACTIVE) == 0);
+ result = process_alloc(process, test.para_base, test.para_limit);
printf(
"... %s\n",
result == test.success ?
if (result) {
if (!test.success) {
printf("... undo\n");
- process_free(processes + test.process);
- processes[test.process].paras = -1;
+ process_free(process);
}
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 ==
- test.blocks
- );
+ process_calc(process, &calc);
+ printf("new core [%d,%d) swap [%d,%d)\n", calc.block_base + calc.core_origin, calc.in_core_block + calc.core_origin, calc.in_core_block + calc.swap_origin, calc.block_limit + calc.swap_origin);
core_hash_init(
test.process,
- (processes[test.process].core_item.base << BLOCK_PARAS_SHIFT) +
- test.para,
- test.paras,
+ (calc.core_origin << BLOCK_PARAS_SHIFT) + test.para_base,
+ test.para_limit - test.para_base,
0
);
}
break;
case PROCESS_TEST_TYPE_REALLOC:
printf(
- "realloc %d %d %d %d %d %d %d %s\n",
+ "realloc %d %d %d %s\n",
test.process,
- test.old_para,
- test.old_paras,
- test.old_blocks,
- test.para,
- test.paras,
- test.blocks,
+ test.old_para_limit,
+ test.para_limit,
test.success ? "true" : "false"
);
- if (processes[test.process].paras == -1)
+ if ((process->flags & PROCESS_FLAGS_ACTIVE) == 0)
printf("... not allocated, ignore\n");
+ else if (test.para_limit < process->para_base)
+ printf("... new limit < base, 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) {
+ old_para_limit = process->para_limit;
+ if (old_para_limit != test.old_para_limit)
printf(
- "... old blocks %d, should be %d\n",
- old_blocks,
- test.old_blocks
+ "... old para limit %d, should be %d\n",
+ old_para_limit,
+ test.para_limit
);
- }
+ process_calc(process, &calc);
+ printf("old core [%d,%d) swap [%d,%d)\n", calc.block_base + calc.core_origin, calc.in_core_block + calc.core_origin, calc.in_core_block + calc.swap_origin, calc.block_limit + calc.swap_origin);
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,
- false
+ (calc.core_origin << BLOCK_PARAS_SHIFT) + test.para_limit,
+ old_para_limit - test.para_limit,
+ test.para_limit - process->para_base
);
+ result = process_realloc(process, test.para_limit, false);
printf(
"... %s\n",
result == test.success ?
if (result) {
if (!test.success) {
printf("... undo\n");
- rassert(
- 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
- );
+ rassert(process_realloc(process, old_para_limit, false));
}
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
- );
- }
+ process_calc(process, &calc);
+ printf("new core [%d,%d) swap [%d,%d)\n", calc.block_base + calc.core_origin, calc.in_core_block + calc.core_origin, calc.in_core_block + calc.swap_origin, calc.block_limit + calc.swap_origin);
core_hash_init(
test.process,
- (processes[test.process].core_item.base << BLOCK_PARAS_SHIFT) +
- new_para +
- old_paras,
- new_paras - old_paras,
- old_paras
+ (calc.core_origin << BLOCK_PARAS_SHIFT) + old_para_limit,
+ test.para_limit - old_para_limit,
+ old_para_limit - process->para_base
);
}
}
break;
case PROCESS_TEST_TYPE_REALLOC_BASE:
printf(
- "realloc_base %d %d %d %d %d %d %d %s\n",
+ "realloc_base %d %d %d %s\n",
test.process,
- test.old_para,
- test.old_paras,
- test.old_blocks,
- test.para,
- test.paras,
- test.blocks,
+ test.old_para_base,
+ test.para_base,
test.success ? "true" : "false"
);
- if (processes[test.process].paras == -1)
+ if ((process->flags & PROCESS_FLAGS_ACTIVE) == 0)
printf("... not allocated, ignore\n");
+ else if (test.para_base > process->para_limit)
+ printf("... new base > limit, 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) {
+ old_para_base = process->para_base;
+ if (old_para_base != test.old_para_base)
printf(
- "... old paras %d, should be %d\n",
- old_paras,
- test.old_paras
+ "... old para base %d, should be %d\n",
+ old_para_base,
+ test.para_base
);
- }
- 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
- );
- }
+ process_calc(process, &calc);
+ printf("old core [%d,%d) swap [%d,%d)\n", calc.block_base + calc.core_origin, calc.in_core_block + calc.core_origin, calc.in_core_block + calc.swap_origin, calc.block_limit + calc.swap_origin);
core_hash_verify(
test.process,
- (processes[test.process].core_item.base << BLOCK_PARAS_SHIFT) +
- old_para,
- old_paras - test.paras,
+ (calc.core_origin << BLOCK_PARAS_SHIFT) + old_para_base,
+ test.para_base - old_para_base,
0
);
- result = process_realloc(
- processes + test.process,
- test.paras,
- true
- );
+ result = process_realloc(process, test.para_base, true);
printf(
"... %s\n",
result == test.success ?
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 ==
- old_blocks
- );
+ rassert(process_realloc(process, old_para_base, true));
}
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)
+ process_calc(process, &calc);
+ printf("new core [%d,%d) swap [%d,%d)\n", calc.block_base + calc.core_origin, calc.in_core_block + calc.core_origin, calc.in_core_block + calc.swap_origin, calc.block_limit + calc.swap_origin);
+ if (test.para_base < test.old_para_base)
core_hash_verify(
test.process,
- (processes[test.process].core_item.base << BLOCK_PARAS_SHIFT) +
- new_para +
- new_paras -
- old_paras,
- old_paras,
+ (calc.core_origin << BLOCK_PARAS_SHIFT) + old_para_base,
+ process->para_limit - old_para_base,
0
);
else
core_hash_verify(
test.process,
- (processes[test.process].core_item.base << BLOCK_PARAS_SHIFT) +
- new_para,
- new_paras,
- old_paras - new_paras
+ (calc.core_origin << BLOCK_PARAS_SHIFT) + test.para_base,
+ process->para_limit - test.para_base,
+ test.para_base - old_para_base
);
core_hash_init(
test.process,
- (processes[test.process].core_item.base << BLOCK_PARAS_SHIFT) +
- new_para,
- new_paras,
+ (calc.core_origin << BLOCK_PARAS_SHIFT) + test.para_base,
+ process->para_limit - test.para_base,
0
);
}
break;
case PROCESS_TEST_TYPE_RUN:
printf("run %d\n", test.process);
- if (processes[test.process].paras == -1)
+ if ((process->flags & PROCESS_FLAGS_ACTIVE) == 0)
printf("... not allocated, ignore\n");
else {
- process_run(processes + test.process);
+ process_run(process);
printf("... ok\n");
}
break;
case PROCESS_TEST_TYPE_FREE:
printf(
- "free %d %d %d %d\n",
+ "free %d %d %d\n",
test.process,
- test.old_para,
- test.old_paras,
- test.old_blocks
+ test.old_para_base,
+ test.old_para_limit
);
- if (processes[test.process].paras == -1)
+ if ((process->flags & PROCESS_FLAGS_ACTIVE) == 0)
printf("... not allocated, ignore\n");
else {
- old_para = processes[test.process].para;
- if (old_para != test.old_para) {
+ old_para_base = process->para_base;
+ if (old_para_base != test.old_para_base)
printf(
- "... old para %d, should be %d\n",
- old_para,
- test.old_para
+ "... old para base %d, should be %d\n",
+ old_para_base,
+ test.para_base
);
- }
- old_paras = processes[test.process].paras;
- if (old_paras != test.old_paras) {
+ old_para_limit = process->para_limit;
+ if (old_para_limit != test.old_para_limit)
printf(
- "... old paras %d, should be %d\n",
- old_paras,
- test.old_paras
+ "... old para limit %d, should be %d\n",
+ old_para_limit,
+ test.para_limit
);
- }
- 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
- );
- }
- process_get_state(processes + test.process, &state);
- printf("old core [%d,%d) swap occupation [%d,%d)\n", state.core_block, state.core_block + state.core_blocks, state.swap_block, state.swap_block + state.swap_blocks);
+ process_calc(process, &calc);
+ printf("old core [%d,%d) swap [%d,%d)\n", calc.block_base + calc.core_origin, calc.in_core_block + calc.core_origin, calc.in_core_block + calc.swap_origin, calc.block_limit + calc.swap_origin);
+ in_core_para = calc.in_core_block << BLOCK_PARAS_SHIFT;
+ if (in_core_para < process->para_base)
+ in_core_para = process->para_base;
+ else if (in_core_para > process->para_limit)
+ in_core_para = process->para_limit;
core_hash_verify(
test.process,
- state.core_para,
- state.core_paras,
+ (calc.core_origin << BLOCK_PARAS_SHIFT) + process->para_base,
+ in_core_para - process->para_base,
0
);
swap_hash_verify(
test.process,
- state.swap_para,
- state.swap_paras,
- state.core_paras
+ (calc.swap_origin << BLOCK_PARAS_SHIFT) + in_core_para,
+ process->para_limit - in_core_para,
+ in_core_para - process->para_base
);
- process_free(processes + test.process);
- processes[test.process].paras = -1;
+ process_free(process);
printf("... ok\n");
}
break;
#endif
printf("final state:\n");
for (i = 0; i < n_processes; ++i) {
- if (processes[i].paras == -1)
+ process = processes + i;
+ if ((process->flags & PROCESS_FLAGS_ACTIVE) == 0)
printf("process %d: not allocated\n", i);
else {
- process_get_state(processes + i, &state);
+ process_calc(process, &calc);
printf(
- "process %d: core [%d,%d) swap occupation [%d,%d)\n",
+ "process %d: core [%d,%d) swap [%d,%d)\n",
i,
- state.core_block,
- state.core_block + state.core_blocks,
- state.swap_block,
- state.swap_block + state.swap_blocks
+ calc.block_base + calc.core_origin,
+ calc.in_core_block + calc.core_origin,
+ calc.in_core_block + calc.swap_origin,
+ calc.block_limit + calc.swap_origin
);
+ in_core_para = calc.in_core_block << BLOCK_PARAS_SHIFT;
+ if (in_core_para < process->para_base)
+ in_core_para = process->para_base;
+ else if (in_core_para > process->para_limit)
+ in_core_para = process->para_limit;
core_hash_verify(
i,
- state.core_para,
- state.core_paras,
- 0
- );
-#ifdef INDIRECT_CORE
- block_pool_free(
- &core_block_pool,
- core_table_mem + state.core_block,
- state.core_blocks
+ (calc.core_origin << BLOCK_PARAS_SHIFT) + process->para_base,
+ in_core_para - process->para_base,
+ 0
);
-#endif /* INDIRECT_CORE */
swap_hash_verify(
i,
- state.swap_para,
- state.swap_paras,
- state.core_paras
+ (calc.swap_origin << BLOCK_PARAS_SHIFT) + in_core_para,
+ process->para_limit - in_core_para,
+ in_core_para - process->para_base
);
-#ifdef INDIRECT_SWAP
- block_pool_free(
- &swap_block_pool,
- swap_table_mem + state.swap_block,
- state.swap_blocks
- );
-#endif /* INDIRECT_SWAP */
+ process_free(process);
}
}