1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-30 04:10:54 -08:00

Catch-up merge from master/...@185556 to branch/2014-03-30/addrset.

Copied from Perforce
 Change: 185563
 ServerID: perforce.ravenbrook.com
This commit is contained in:
Gareth Rees 2014-04-15 13:14:50 +01:00
commit 42f18f93af
116 changed files with 1597 additions and 934 deletions

View file

@ -16,5 +16,8 @@ TAGS
*.dSYM
code/*/*/*.d
*.pyc
test/obj
test/test/log
test/test/obj
....gcda
....gcno

View file

@ -1,7 +1,7 @@
/* abq.c: QUEUE IMPLEMENTATION
*
* $Id$
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
* .purpose: A fixed-length FIFO queue.
*
@ -185,18 +185,10 @@ Res ABQDescribe(ABQ abq, ABQDescribeElement describeElement, mps_lib_FILE *strea
if(res != ResOK)
return res;
res = METER_WRITE(abq->push, stream);
if(res != ResOK)
return res;
res = METER_WRITE(abq->pop, stream);
if(res != ResOK)
return res;
res = METER_WRITE(abq->peek, stream);
if(res != ResOK)
return res;
res = METER_WRITE(abq->delete, stream);
if(res != ResOK)
return res;
METER_WRITE(abq->push, stream);
METER_WRITE(abq->pop, stream);
METER_WRITE(abq->peek, stream);
METER_WRITE(abq->delete, stream);
res = WriteF(stream, "}\n", NULL);
if(res != ResOK)
@ -311,7 +303,7 @@ static void *ABQElement(ABQ abq, Index index) {
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -7,15 +7,16 @@
#include "abq.h"
#include "mps.h"
#include "mpsavm.h"
#include "mpscmfs.h"
#include "mpstd.h"
#include "testlib.h"
#include <stdlib.h>
#include <stdio.h> /* printf */
SRCID(abqtest, "$Id$");
static mps_pool_t pool;
static ABQStruct abq; /* the ABQ which we will use */
static Size abqSize; /* the size of the current ABQ */
@ -50,9 +51,12 @@ static TestBlock testBlocks = NULL;
static TestBlock CreateTestBlock(unsigned no)
{
TestBlock b = malloc(sizeof(TestBlockStruct));
cdie(b != NULL, "malloc");
TestBlock b;
mps_addr_t p;
die(mps_alloc(&p, pool, sizeof(TestBlockStruct)), "alloc");
b = p;
b->next = testBlocks;
b->id = no;
b->base = 0;
@ -78,7 +82,7 @@ static void DestroyTestBlock(TestBlock b)
}
}
free(b);
mps_free(pool, b, sizeof(TestBlockStruct));
}
typedef struct TestClosureStruct *TestClosure;
@ -146,9 +150,6 @@ static void step(void)
}
}
#define testArenaSIZE (((size_t)4)<<20)
extern int main(int argc, char *argv[])
{
mps_arena_t arena;
@ -158,9 +159,14 @@ extern int main(int argc, char *argv[])
abqSize = 0;
die(mps_arena_create(&arena, mps_arena_class_vm(), testArenaSIZE),
die(mps_arena_create_k(&arena, mps_arena_class_vm(), mps_args_none),
"mps_arena_create");
MPS_ARGS_BEGIN(args) {
MPS_ARGS_ADD(args, MPS_KEY_MFS_UNIT_SIZE, sizeof(TestBlockStruct));
die(mps_pool_create_k(&pool, arena, mps_class_mfs(), args), "pool_create");
} MPS_ARGS_END(args);
die(ABQInit((Arena)arena, &abq, NULL, ABQ_SIZE, sizeof(TestBlock)),
"ABQInit");

View file

@ -35,14 +35,14 @@
#include "fmtscheme.h"
#define OBJ_LEN (1u << 4)
#define OBJ_COUNT 1
#define OBJ_COUNT 10
static void test_air(int interior, int stack)
{
size_t n_finalized = 0;
size_t i, j;
obj_t *s[OBJ_COUNT] = {0};
mps_root_t root;
mps_root_t root = NULL;
if (!stack) {
mps_addr_t *p = (void *)s;
die(mps_root_create_table(&root, scheme_arena, mps_rank_ambig(), 0, p,
@ -90,20 +90,15 @@ static mps_gen_param_s obj_gen_params[] = {
{ 170, 0.45 }
};
static void test_main(int interior, int stack)
static void test_main(void *marker, int interior, int stack)
{
mps_res_t res;
mps_chain_t obj_chain;
mps_fmt_t obj_fmt;
mps_thr_t thread;
mps_root_t reg_root;
void *marker = &marker;
mps_root_t reg_root = NULL;
MPS_ARGS_BEGIN(args) {
MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, 1 << 20);
MPS_ARGS_DONE(args);
res = mps_arena_create_k(&scheme_arena, mps_arena_class_vm(), args);
} MPS_ARGS_END(args);
res = mps_arena_create_k(&scheme_arena, mps_arena_class_vm(), mps_args_none);
if (res != MPS_RES_OK) error("Couldn't create arena");
res = mps_chain_create(&obj_chain, scheme_arena,
@ -149,12 +144,14 @@ static void test_main(int interior, int stack)
int main(int argc, char *argv[])
{
void *marker = &marker;
testlib_init(argc, argv);
test_main(TRUE, TRUE);
test_main(TRUE, FALSE);
/* not test_main(FALSE, TRUE) -- see .fail.lii6ll. */
test_main(FALSE, FALSE);
test_main(marker, TRUE, TRUE);
test_main(marker, TRUE, FALSE);
/* not test_main(marker, FALSE, TRUE) -- see .fail.lii6ll. */
test_main(marker, FALSE, FALSE);
printf("%s: Conclusion: Failed to find any defects.\n", argv[0]);
return 0;

View file

@ -12,13 +12,10 @@
#include "mpscamc.h"
#include "mpsavm.h"
#include "mpstd.h"
#ifdef MPS_OS_W3
#include "mpsw3.h"
#endif
#include "mps.h"
#include "mpslib.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h> /* fflush, printf, putchar */
/* These values have been tuned in the hope of getting one dynamic collection. */
@ -81,19 +78,6 @@ static void report(mps_arena_t arena)
printf(" not_condemned %"PRIuLONGEST"\n", (ulongest_t)not_condemned);
printf(" clock: %"PRIuLONGEST"\n", (ulongest_t)mps_message_clock(arena, message));
printf("}\n");
if(condemned > (gen1SIZE + gen2SIZE + (size_t)128) * 1024) {
/* When condemned size is larger than could happen in a gen 2
* collection (discounting ramps, natch), guess that was a dynamic
* collection, and reset the commit limit, so it doesn't run out.
*
* GDR 2013-03-12: Fiddling with the commit limit was causing
* the test to fail sometimes (see job003440), so I've commented
* out this feature.
*/
/* die(mps_arena_commit_limit_set(arena, 2 * testArenaSIZE), "set limit"); */
}
} else {
cdie(0, "unknown message type");
break;
@ -101,14 +85,12 @@ static void report(mps_arena_t arena)
mps_message_discard(arena, message);
}
return;
}
/* make -- create one new object */
static mps_addr_t make(void)
static mps_addr_t make(size_t rootsCount)
{
size_t length = rnd() % (2*avLEN);
size_t size = (length+2) * sizeof(mps_word_t);
@ -119,7 +101,7 @@ static mps_addr_t make(void)
MPS_RESERVE_BLOCK(res, p, ap, size);
if (res)
die(res, "MPS_RESERVE_BLOCK");
res = dylan_init(p, size, exactRoots, exactRootsCOUNT);
res = dylan_init(p, size, exactRoots, rootsCount);
if (res)
die(res, "dylan_init");
} while(!mps_commit(ap, p, size));
@ -141,7 +123,7 @@ static void test_stepper(mps_addr_t object, mps_fmt_t fmt, mps_pool_t pool,
/* test -- the body of the test */
static void test(mps_arena_t arena)
static void test(mps_arena_t arena, mps_class_t pool_class, size_t roots_count)
{
mps_fmt_t format;
mps_chain_t chain;
@ -157,7 +139,7 @@ static void test(mps_arena_t arena)
die(dylan_fmt(&format, arena), "fmt_create");
die(mps_chain_create(&chain, arena, genCOUNT, testChain), "chain_create");
die(mps_pool_create(&pool, arena, mps_class_amc(), format, chain),
die(mps_pool_create(&pool, arena, pool_class, format, chain),
"pool_create(amc)");
die(mps_ap_create(&ap, pool, mps_rank_exact()), "BufferCreate");
@ -269,13 +251,13 @@ static void test(mps_arena_t arena)
i = (r >> 1) % exactRootsCOUNT;
if (exactRoots[i] != objNULL)
cdie(dylan_check(exactRoots[i]), "dying root check");
exactRoots[i] = make();
exactRoots[i] = make(roots_count);
if (exactRoots[(exactRootsCOUNT-1) - i] != objNULL)
dylan_write(exactRoots[(exactRootsCOUNT-1) - i],
exactRoots, exactRootsCOUNT);
} else {
i = (r >> 1) % ambigRootsCOUNT;
ambigRoots[(ambigRootsCOUNT-1) - i] = make();
ambigRoots[(ambigRootsCOUNT-1) - i] = make(roots_count);
/* Create random interior pointers */
ambigRoots[i] = (mps_addr_t)((char *)(ambigRoots[i/2]) + 1);
}
@ -313,13 +295,10 @@ int main(int argc, char *argv[])
"arena_create");
mps_message_type_enable(arena, mps_message_type_gc());
mps_message_type_enable(arena, mps_message_type_gc_start());
/* GDR 2013-03-12: Fiddling with the commit limit was causing
* the test to fail sometimes (see job003440), so I've commented
* out this feature.
*/
/*die(mps_arena_commit_limit_set(arena, testArenaSIZE), "set limit");*/
die(mps_arena_commit_limit_set(arena, 2*testArenaSIZE), "set limit");
die(mps_thread_reg(&thread, arena), "thread_reg");
test(arena);
test(arena, mps_class_amc(), exactRootsCOUNT);
test(arena, mps_class_amcz(), 0);
mps_thread_dereg(thread);
report(arena);
mps_arena_destroy(arena);

View file

@ -12,12 +12,9 @@
#include "mpscamc.h"
#include "mpsavm.h"
#include "mpstd.h"
#ifdef MPS_OS_W3
#include "mpsw3.h"
#endif
#include "mps.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h> /* fflush, printf, putchar */
/* These values have been tuned in the hope of getting one dynamic collection. */
@ -51,7 +48,7 @@ static mps_addr_t exactRoots[exactRootsCOUNT];
static mps_addr_t ambigRoots[ambigRootsCOUNT];
static mps_addr_t bogusRoots[bogusRootsCOUNT];
static mps_addr_t make(void)
static mps_addr_t make(size_t roots_count)
{
size_t length = rnd() % (2*avLEN);
size_t size = (length+2) * sizeof(mps_word_t);
@ -63,7 +60,7 @@ static mps_addr_t make(void)
if (res)
die(res, "MPS_RESERVE_BLOCK");
userP = (mps_addr_t)((char*)p + headerSIZE);
res = dylan_init(userP, size, exactRoots, exactRootsCOUNT);
res = dylan_init(userP, size, exactRoots, roots_count);
if (res)
die(res, "dylan_init");
((int*)p)[0] = realHeader;
@ -94,27 +91,14 @@ static void report(mps_arena_t arena)
printf("not_condemned %"PRIuLONGEST"\n", (ulongest_t)not_condemned);
mps_message_discard(arena, message);
if (condemned > (gen1SIZE + gen2SIZE + (size_t)128) * 1024) {
/* When condemned size is larger than could happen in a gen 2
* collection (discounting ramps, natch), guess that was a dynamic
* collection, and reset the commit limit, so it doesn't run out.
*
* GDR 2013-03-07: Fiddling with the commit limit was causing
* the test to fail sometimes (see job003432), so I've commented
* out this feature.
*/
/*die(mps_arena_commit_limit_set(arena, 2 * testArenaSIZE), "set limit");*/
}
}
}
/* test -- the body of the test */
static void *test(void *arg, size_t s)
static void *test(mps_arena_t arena, mps_class_t pool_class, size_t roots_count)
{
mps_arena_t arena;
mps_fmt_t format;
mps_chain_t chain;
mps_root_t exactRoot, ambigRoot, bogusRoot;
@ -125,13 +109,10 @@ static void *test(void *arg, size_t s)
mps_ap_t busy_ap;
mps_addr_t busy_init;
arena = (mps_arena_t)arg;
(void)s; /* unused */
die(EnsureHeaderFormat(&format, arena), "fmt_create");
die(mps_chain_create(&chain, arena, genCOUNT, testChain), "chain_create");
die(mps_pool_create(&pool, arena, mps_class_amc(), format, chain),
die(mps_pool_create(&pool, arena, pool_class, format, chain),
"pool_create(amc)");
die(mps_ap_create(&ap, pool, mps_rank_exact()), "BufferCreate");
@ -220,13 +201,13 @@ static void *test(void *arg, size_t s)
i = (r >> 1) % exactRootsCOUNT;
if (exactRoots[i] != objNULL)
die(HeaderFormatCheck(exactRoots[i]), "wrapper check");
exactRoots[i] = make();
exactRoots[i] = make(roots_count);
if (exactRoots[(exactRootsCOUNT-1) - i] != objNULL)
dylan_write(exactRoots[(exactRootsCOUNT-1) - i],
exactRoots, exactRootsCOUNT);
} else {
i = (r >> 1) % ambigRootsCOUNT;
ambigRoots[(ambigRootsCOUNT-1) - i] = make();
ambigRoots[(ambigRootsCOUNT-1) - i] = make(roots_count);
/* Create random interior pointers */
ambigRoots[i] = (mps_addr_t)((char *)(ambigRoots[i/2]) + 1);
}
@ -261,20 +242,16 @@ int main(int argc, char *argv[])
{
mps_arena_t arena;
mps_thr_t thread;
void *r;
testlib_init(argc, argv);
die(mps_arena_create(&arena, mps_arena_class_vm(), 3*testArenaSIZE),
die(mps_arena_create(&arena, mps_arena_class_vm(), 2*testArenaSIZE),
"arena_create\n");
mps_message_type_enable(arena, mps_message_type_gc());
/* GDR 2013-03-07: Fiddling with the commit limit was causing
* the test to fail sometimes (see job003432), so I've commented
* out this feature.
*/
/*die(mps_arena_commit_limit_set(arena, testArenaSIZE), "set limit");*/
die(mps_arena_commit_limit_set(arena, 2*testArenaSIZE), "set limit");
die(mps_thread_reg(&thread, arena), "thread_reg");
mps_tramp(&r, test, arena, 0);
test(arena, mps_class_amc(), exactRootsCOUNT);
test(arena, mps_class_amcz(), 0);
mps_thread_dereg(thread);
mps_arena_destroy(arena);

View file

@ -4,21 +4,34 @@
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
* Portions copyright (c) 2002 Global Graphics Software.
*
* .posix: This is Posix only.
* .mode: This test case has two modes:
*
* .mode.walk: In this mode, the main thread parks the arena half way
* through the test case and runs mps_arena_formatted_objects_walk().
* This checks that walking works while the other threads continue to
* allocate in the background.
*
* .mode.commit: In this mode, the arena's commit limit is set. This
* checks that the MPS can make progress inside a tight limit in the
* presence of allocation on multiple threads. But this is
* incompatible with .mode.walk: if the arena is parked, then the
* arena has no chance to make progress.
*/
#define _POSIX_C_SOURCE 199309L
#include "fmtdy.h"
#include "fmtdytst.h"
#include "testlib.h"
#include "testthr.h"
#include "mpslib.h"
#include "mpscamc.h"
#include "mpsavm.h"
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <time.h>
#include <stdio.h> /* fflush, printf, putchar */
enum {
ModeWALK = 0, /* .mode.walk */
ModeCOMMIT = 1 /* .mode.commit */
};
/* These values have been tuned in the hope of getting one dynamic collection. */
@ -43,7 +56,6 @@ static mps_gen_param_s testChain[genCOUNT] = {
#define objNULL ((mps_addr_t)MPS_WORD_CONST(0xDECEA5ED))
static mps_pool_t pool;
static mps_addr_t exactRoots[exactRootsCOUNT];
static mps_addr_t ambigRoots[ambigRootsCOUNT];
@ -67,26 +79,20 @@ static void report(mps_arena_t arena)
printf("not_condemned %"PRIuLONGEST"\n", (ulongest_t)not_condemned);
mps_message_discard(arena, message);
if (condemned > (gen1SIZE + gen2SIZE + (size_t)128) * 1024)
/* When condemned size is larger than could happen in a gen 2
* collection (discounting ramps, natch), guess that was a dynamic
* collection, and reset the commit limit, so it doesn't run out. */
die(mps_arena_commit_limit_set(arena, 2 * testArenaSIZE), "set limit");
}
}
mps_arena_t arena;
mps_fmt_t format;
mps_chain_t chain;
mps_root_t exactRoot, ambigRoot;
unsigned long objs = 0;
static mps_arena_t arena;
static mps_fmt_t format;
static mps_chain_t chain;
static mps_root_t exactRoot, ambigRoot;
static unsigned long objs = 0;
/* make -- create one new object */
static mps_addr_t make(mps_ap_t ap)
static mps_addr_t make(mps_ap_t ap, size_t roots_count)
{
size_t length = rnd() % (2*avLEN);
size_t size = (length+2) * sizeof(mps_word_t);
@ -97,7 +103,7 @@ static mps_addr_t make(mps_ap_t ap)
MPS_RESERVE_BLOCK(res, p, ap, size);
if (res)
die(res, "MPS_RESERVE_BLOCK");
res = dylan_init(p, size, exactRoots, exactRootsCOUNT);
res = dylan_init(p, size, exactRoots, roots_count);
if (res)
die(res, "dylan_init");
} while(!mps_commit(ap, p, size));
@ -108,16 +114,16 @@ static mps_addr_t make(mps_ap_t ap)
/* test_stepper -- stepping function for walk */
static void test_stepper(mps_addr_t object, mps_fmt_t fmt, mps_pool_t pol,
static void test_stepper(mps_addr_t object, mps_fmt_t fmt, mps_pool_t pool,
void *p, size_t s)
{
testlib_unused(object); testlib_unused(fmt); testlib_unused(pol);
testlib_unused(object); testlib_unused(fmt); testlib_unused(pool);
testlib_unused(s);
(*(unsigned long *)p)++;
}
/* init -- initialize pool and roots */
/* init -- initialize roots and chain */
static void init(void)
{
@ -126,9 +132,6 @@ static void init(void)
die(dylan_fmt(&format, arena), "fmt_create");
die(mps_chain_create(&chain, arena, genCOUNT, testChain), "chain_create");
die(mps_pool_create(&pool, arena, mps_class_amc(), format, chain),
"pool_create(amc)");
for(i = 0; i < exactRootsCOUNT; ++i)
exactRoots[i] = objNULL;
for(i = 0; i < ambigRootsCOUNT; ++i)
@ -146,13 +149,12 @@ static void init(void)
}
/* finish -- finish pool and roots */
/* finish -- finish roots and chain */
static void finish(void)
{
mps_root_destroy(exactRoot);
mps_root_destroy(ambigRoot);
mps_pool_destroy(pool);
mps_chain_destroy(chain);
mps_fmt_destroy(format);
}
@ -160,7 +162,7 @@ static void finish(void)
/* churn -- create an object and install into roots */
static void churn(mps_ap_t ap)
static void churn(mps_ap_t ap, size_t roots_count)
{
size_t i;
size_t r;
@ -171,22 +173,52 @@ static void churn(mps_ap_t ap)
i = (r >> 1) % exactRootsCOUNT;
if (exactRoots[i] != objNULL)
cdie(dylan_check(exactRoots[i]), "dying root check");
exactRoots[i] = make(ap);
exactRoots[i] = make(ap, roots_count);
if (exactRoots[(exactRootsCOUNT-1) - i] != objNULL)
dylan_write(exactRoots[(exactRootsCOUNT-1) - i],
exactRoots, exactRootsCOUNT);
} else {
i = (r >> 1) % ambigRootsCOUNT;
ambigRoots[(ambigRootsCOUNT-1) - i] = make(ap);
ambigRoots[(ambigRootsCOUNT-1) - i] = make(ap, roots_count);
/* Create random interior pointers */
ambigRoots[i] = (mps_addr_t)((char *)(ambigRoots[i/2]) + 1);
}
}
typedef struct closure_s {
mps_pool_t pool;
size_t roots_count;
} closure_s, *closure_t;
static void *kid_thread(void *arg)
{
void *marker = &marker;
mps_thr_t thread;
mps_root_t reg_root;
mps_ap_t ap;
closure_t cl = arg;
die(mps_thread_reg(&thread, (mps_arena_t)arena), "thread_reg");
die(mps_root_create_reg(&reg_root, arena, mps_rank_ambig(), 0, thread,
mps_stack_scan_ambig, marker, 0), "root_create");
die(mps_ap_create(&ap, cl->pool, mps_rank_exact()), "BufferCreate(fooey)");
while(mps_collections(arena) < collectionsCOUNT) {
churn(ap, cl->roots_count);
}
mps_ap_destroy(ap);
mps_root_destroy(reg_root);
mps_thread_dereg(thread);
return NULL;
}
/* test -- the body of the test */
static void *test(void *arg, size_t s)
static void *test_pool(mps_class_t pool_class, size_t roots_count, int mode)
{
size_t i;
mps_word_t collections, rampSwitch;
@ -194,9 +226,19 @@ static void *test(void *arg, size_t s)
int ramping;
mps_ap_t ap, busy_ap;
mps_addr_t busy_init;
mps_pool_t pool;
testthr_t kids[10];
closure_s cl;
int walked = FALSE, ramped = FALSE;
arena = (mps_arena_t)arg;
(void)s; /* unused */
die(mps_pool_create(&pool, arena, pool_class, format, chain),
"pool_create(amc)");
cl.pool = pool;
cl.roots_count = roots_count;
for (i = 0; i < sizeof(kids)/sizeof(kids[0]); ++i)
testthr_create(&kids[i], kid_thread, &cl);
die(mps_ap_create(&ap, pool, mps_rank_exact()), "BufferCreate");
die(mps_ap_create(&busy_ap, pool, mps_rank_exact()), "BufferCreate 2");
@ -217,21 +259,23 @@ static void *test(void *arg, size_t s)
if (collections != c) {
collections = c;
printf("\nCollection %lu started, %lu objects.\n", c, objs);
printf("\nCollection %lu started, %lu objects, committed=%lu.\n",
c, objs, (unsigned long)mps_arena_committed(arena));
report(arena);
for (i = 0; i < exactRootsCOUNT; ++i)
cdie(exactRoots[i] == objNULL || dylan_check(exactRoots[i]),
"all roots check");
if (collections == collectionsCOUNT / 2) {
if (mode == ModeWALK && collections >= collectionsCOUNT / 2 && !walked) {
unsigned long object_count = 0;
mps_arena_park(arena);
mps_arena_formatted_objects_walk(arena, test_stepper, &object_count, 0);
mps_arena_release(arena);
printf("stepped on %lu objects.\n", object_count);
walked = TRUE;
}
if (collections == rampSwitch) {
if (collections >= rampSwitch && !ramped) {
int begin_ramp = !ramping
|| /* Every other time, switch back immediately. */ (collections & 1);
@ -256,9 +300,10 @@ static void *test(void *arg, size_t s)
ramping = 1;
}
}
ramped = TRUE;
}
churn(ap);
churn(ap, roots_count);
r = (size_t)rnd();
@ -276,79 +321,45 @@ static void *test(void *arg, size_t s)
mps_ap_destroy(busy_ap);
mps_ap_destroy(ap);
for (i = 0; i < sizeof(kids)/sizeof(kids[0]); ++i)
testthr_join(&kids[i], NULL);
mps_pool_destroy(pool);
return NULL;
}
static void *fooey2(void *arg, size_t s)
{
mps_ap_t ap;
(void)arg; (void)s; /* unused */
die(mps_ap_create(&ap, pool, mps_rank_exact()), "BufferCreate(fooey)");
while(mps_collections(arena) < collectionsCOUNT) {
churn(ap);
}
mps_ap_destroy(ap);
return NULL;
}
static void *fooey(void* childIsFinishedReturn)
{
void *r;
mps_thr_t thread;
void *marker = &marker;
mps_root_t reg_root;
die(mps_thread_reg(&thread, (mps_arena_t)arena), "thread_reg");
die(mps_root_create_reg(&reg_root, arena, mps_rank_ambig(), 0, thread,
mps_stack_scan_ambig, marker, 0), "root_create");
mps_tramp(&r, fooey2, NULL, 0);
mps_root_destroy(reg_root);
mps_thread_dereg(thread);
*(int *)childIsFinishedReturn = 1;
return r;
}
int main(int argc, char *argv[])
static void test_arena(int mode)
{
mps_thr_t thread;
mps_root_t reg_root;
void *marker = &marker;
pthread_t kids[10];
unsigned i;
void *r;
int childIsFinished = 0;
testlib_init(argc, argv);
die(mps_arena_create(&arena, mps_arena_class_vm(), testArenaSIZE),
"arena_create");
if (mode == ModeCOMMIT)
die(mps_arena_commit_limit_set(arena, 2 * testArenaSIZE), "set limit");
mps_message_type_enable(arena, mps_message_type_gc());
init();
die(mps_thread_reg(&thread, arena), "thread_reg");
die(mps_root_create_reg(&reg_root, arena, mps_rank_ambig(), 0, thread,
mps_stack_scan_ambig, marker, 0), "root_create");
for (i = 0; i < sizeof(kids)/sizeof(kids[0]); ++i) {
int err = pthread_create(&kids[i], NULL, fooey, (void *)&childIsFinished);
if (err != 0)
error("pthread_create returned %d", err);
}
mps_tramp(&r, test, arena, 0);
mps_stack_scan_ambig, marker, 0), "root_create");
test_pool(mps_class_amc(), exactRootsCOUNT, mode);
test_pool(mps_class_amcz(), 0, mode);
mps_root_destroy(reg_root);
mps_thread_dereg(thread);
for (i = 0; i < sizeof(kids)/sizeof(kids[0]); ++i) {
int err = pthread_join(kids[i], NULL);
if (err != 0)
error("pthread_join returned %d", err);
}
finish();
report(arena);
mps_arena_destroy(arena);
}
int main(int argc, char *argv[])
{
testlib_init(argc, argv);
test_arena(ModeWALK);
test_arena(ModeCOMMIT);
printf("%s: Conclusion: Failed to find any defects.\n", argv[0]);
return 0;

View file

@ -15,14 +15,9 @@
#include "mpscams.h"
#include "mpsavm.h"
#include "mpstd.h"
#ifdef MPS_OS_W3
#include "mpsw3.h"
#endif
#include "mps.h"
#include <stdlib.h>
#include <stdarg.h>
#include <math.h>
#include <string.h>
#include <stdio.h> /* fflush, printf */
#define exactRootsCOUNT 50

View file

@ -13,14 +13,9 @@
#include "mpscams.h"
#include "mpsavm.h"
#include "mpstd.h"
#ifdef MPS_OS_W3
#include "mpsw3.h"
#endif
#include "mps.h"
#include <stdlib.h>
#include <stdarg.h>
#include <math.h>
#include <string.h>
#include <stdio.h> /* fflush, printf */
#define exactRootsCOUNT 50

View file

@ -16,7 +16,7 @@
#include "testlib.h"
#include "mpslib.h"
#include <stdarg.h>
#include <stdio.h> /* printf */
#include <stdlib.h> /* malloc */

View file

@ -14,8 +14,6 @@
* being allocated; this requires using two adjacent zones.
*/
#include <stdlib.h>
#include "mpm.h"
#include "poolmv.h"
#include "testlib.h"
@ -23,6 +21,9 @@
#include "mpsavm.h"
#include "mpsacl.h"
#include <stdio.h> /* printf */
#include <stdlib.h> /* malloc */
#define tractsSIZE 500

View file

@ -480,7 +480,7 @@ ARG_DEFINE_KEY(arena_contracted, Fun);
static Res VMArenaInit(Arena *arenaReturn, ArenaClass class, ArgList args)
{
Size userSize; /* size requested by user */
Size userSize = VM_ARENA_SIZE_DEFAULT; /* size requested by user */
Size chunkSize; /* size actually created */
Size vmArenaSize; /* aligned size of VMArenaStruct */
Res res;
@ -495,8 +495,8 @@ static Res VMArenaInit(Arena *arenaReturn, ArenaClass class, ArgList args)
AVER(class == VMArenaClassGet());
AVERT(ArgList, args);
ArgRequire(&arg, args, MPS_KEY_ARENA_SIZE);
userSize = arg.val.size;
if (ArgPick(&arg, args, MPS_KEY_ARENA_SIZE))
userSize = arg.val.size;
AVER(userSize > 0);
@ -593,6 +593,8 @@ static void VMArenaFinish(Arena arena)
AVERT(VMArena, vmArena);
arenaVM = vmArena->vm;
EVENT1(ArenaDestroy, vmArena);
/* destroy all chunks, including the primary */
arena->primary = NULL;
RING_FOR(node, &arena->chunkRing, next) {
@ -612,7 +614,6 @@ static void VMArenaFinish(Arena arena)
VMUnmap(arenaVM, VMBase(arenaVM), VMLimit(arenaVM));
VMDestroy(arenaVM);
EVENT1(ArenaDestroy, vmArena);
}

View file

@ -1,7 +1,7 @@
/* arg.h: Keyword argument lists
*
* $Id$
* Copyright (c) 2013 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2013-2014 Ravenbrook Limited. See end of file for license.
*
* .source: See <design/keyword-arguments.rst>.
*/
@ -28,6 +28,7 @@ typedef struct mps_key_s {
} KeyStruct;
#define ARG_DEFINE_KEY(id, type) \
extern const KeyStruct _mps_key_##id; \
const KeyStruct _mps_key_##id = {KeySig, #id, ArgCheck##type}
#define argsNone mps_args_none
@ -62,7 +63,7 @@ extern Bool ArgCheckPool(Arg arg);
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2013 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -16,10 +16,9 @@
#include "mpslib.h"
#include "mps.h"
#include "mpstd.h"
#ifdef MPS_OS_W3
#include "mpsw3.h"
#endif
#include <string.h>
#include <stdio.h> /* printf */
#include <string.h> /* strlen */
#define testArenaSIZE ((size_t)64<<20)

View file

@ -17,10 +17,9 @@
#include "mpslib.h"
#include "mps.h"
#include "mpstd.h"
#ifdef MPS_OS_W3
#include "mpsw3.h"
#endif
#include <string.h>
#include <string.h> /* strlen */
#include <stdio.h> /* printf */
#define testArenaSIZE ((size_t)64<<20)

View file

@ -13,16 +13,13 @@
#include "mpsavm.h"
#include "fmtdy.h"
#include "testlib.h"
#include "testthr.h"
#include "mpslib.h"
#include "mps.h"
#include "mpstd.h"
#ifdef MPS_OS_W3
#include "mpsw3.h"
#endif
#include <string.h>
#if defined(MPS_OS_LI) || defined(MPS_OS_FR) || defined(MPS_OS_XC)
#include <pthread.h>
#endif
#include <stdio.h> /* printf, puts */
#include <string.h> /* strlen */
#define testArenaSIZE ((size_t)64<<20)
@ -314,7 +311,7 @@ static void *setup_thr(void *v)
int main(int argc, char *argv[])
{
mps_arena_t arena;
pthread_t pthread1;
testthr_t thread1;
testlib_init(argc, argv);
@ -324,9 +321,9 @@ int main(int argc, char *argv[])
die(mps_arena_create(&arena, mps_arena_class_vm(), testArenaSIZE),
"arena_create\n");
pthread_create(&pthread1, NULL, setup_thr, (void *)arena);
testthr_create(&thread1, setup_thr, arena);
setup_thr(arena);
pthread_join(pthread1, NULL);
testthr_join(&thread1, NULL);
mps_arena_destroy(arena);
printf("%s: Conclusion: Failed to find any defects.\n", argv[0]);

View file

@ -18,7 +18,7 @@
#include "testlib.h"
#include "mpslib.h"
#include <stdlib.h>
#include <stdio.h> /* printf */
SRCID(btcv, "$Id$");

View file

@ -10,11 +10,10 @@
#include "mpsavm.h"
#include "testlib.h"
#include "mpslib.h"
#include <stdlib.h>
#include <stdarg.h>
#include "mpstd.h"
#include <time.h>
#include <stdio.h> /* fflush, fgets, printf, putchar, puts */
#include <stdlib.h> /* exit, strtol */
SRCID(bttest, "$Id$");

View file

@ -980,14 +980,14 @@ Bool BufferIsTrappedByMutator(Buffer buffer)
*
* Just represent the two patterns by two different pointers to dummies. */
AllocPatternStruct AllocPatternRampStruct = {'\0'};
static AllocPatternStruct AllocPatternRampStruct = {'\0'};
AllocPattern AllocPatternRamp(void)
{
return &AllocPatternRampStruct;
}
AllocPatternStruct AllocPatternRampCollectAllStruct = {'\0'};
static AllocPatternStruct AllocPatternRampCollectAllStruct = {'\0'};
AllocPattern AllocPatternRampCollectAll(void)
{
@ -1075,7 +1075,7 @@ static Res bufferTrivInit(Buffer buffer, Pool pool, ArgList args)
AVERT(Buffer, buffer);
AVERT(Pool, pool);
UNUSED(args);
EVENT3(BufferInit, buffer, pool, buffer->isMutator);
EVENT3(BufferInit, buffer, pool, BOOL(buffer->isMutator));
return ResOK;
}
@ -1288,7 +1288,7 @@ static Res segBufInit(Buffer buffer, Pool pool, ArgList args)
segbuf->rankSet = RankSetEMPTY;
AVERT(SegBuf, segbuf);
EVENT3(BufferInitSeg, buffer, pool, buffer->isMutator);
EVENT3(BufferInitSeg, buffer, pool, BOOL(buffer->isMutator));
return ResOK;
}
@ -1515,7 +1515,7 @@ static Res rankBufInit(Buffer buffer, Pool pool, ArgList args)
BufferSetRankSet(buffer, RankSetSingle(rank));
/* There's nothing to check that the superclass doesn't, so no AVERT. */
EVENT4(BufferInitRank, buffer, pool, buffer->isMutator, rank);
EVENT4(BufferInitRank, buffer, pool, BOOL(buffer->isMutator), rank);
return ResOK;
}

View file

@ -1174,8 +1174,7 @@ static Res cbsDescribe(Land land, mps_lib_FILE *stream)
res = SplayTreeDescribe(cbsSplay(cbs), stream, describe);
if (res != ResOK) return res;
res = METER_WRITE(cbs->treeSearch, stream);
if (res != ResOK) return res;
METER_WRITE(cbs->treeSearch, stream);
res = WriteF(stream, "}\n", NULL);
return res;

View file

@ -158,7 +158,7 @@ SNC = poolsnc.c
POOLN = pooln.c
MV2 = poolmv2.c
MVFF = poolmvff.c
TESTLIB = testlib.c
TESTLIB = testlib.c testthrix.c
FMTDY = fmtdy.c fmtno.c
FMTDYTST = fmtdy.c fmtno.c fmtdytst.c
FMTHETST = fmthe.c fmtdy.c fmtno.c fmtdytst.c
@ -294,6 +294,7 @@ TEST_TARGETS=\
landtest \
locbwcss \
lockcov \
lockut \
locusss \
locv \
messtest \
@ -492,6 +493,9 @@ $(PFM)/$(VARIETY)/locbwcss: $(PFM)/$(VARIETY)/locbwcss.o \
$(PFM)/$(VARIETY)/lockcov: $(PFM)/$(VARIETY)/lockcov.o \
$(TESTLIBOBJ) $(PFM)/$(VARIETY)/mps.a
$(PFM)/$(VARIETY)/lockut: $(PFM)/$(VARIETY)/lockut.o \
$(TESTLIBOBJ) $(PFM)/$(VARIETY)/mps.a
$(PFM)/$(VARIETY)/locusss: $(PFM)/$(VARIETY)/locusss.o \
$(TESTLIBOBJ) $(PFM)/$(VARIETY)/mps.a

View file

@ -1,7 +1,7 @@
# commpost.nmk: SECOND COMMON FRAGMENT FOR PLATFORMS USING NMAKE -*- makefile -*-
#
# $Id$
# Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license.
# Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
#
# DESCRIPTION
#
@ -146,6 +146,10 @@ $(PFM)\$(VARIETY)\awluthe.exe: $(PFM)\$(VARIETY)\awluthe.obj \
$(FMTTESTOBJ) \
$(PFM)\$(VARIETY)\mps.lib $(TESTLIBOBJ)
$(PFM)\$(VARIETY)\awlutth.exe: $(PFM)\$(VARIETY)\awlutth.obj \
$(FMTTESTOBJ) \
$(PFM)\$(VARIETY)\mps.lib $(TESTLIBOBJ)
$(PFM)\$(VARIETY)\btcv.exe: $(PFM)\$(VARIETY)\btcv.obj \
$(PFM)\$(VARIETY)\mps.lib $(TESTLIBOBJ)
@ -155,6 +159,9 @@ $(PFM)\$(VARIETY)\bttest.exe: $(PFM)\$(VARIETY)\bttest.obj \
$(PFM)\$(VARIETY)\cvmicv.exe: $(PFM)\$(VARIETY)\cvmicv.obj \
$(PFM)\$(VARIETY)\mps.lib $(FMTTESTOBJ) $(TESTLIBOBJ)
$(PFM)\$(VARIETY)\djbench.exe: $(PFM)\$(VARIETY)\djbench.obj \
$(PFM)\$(VARIETY)\mps.lib $(TESTLIBOBJ)
$(PFM)\$(VARIETY)\exposet0.exe: $(PFM)\$(VARIETY)\exposet0.obj \
$(PFM)\$(VARIETY)\mps.lib $(FMTTESTOBJ) $(TESTLIBOBJ)
@ -170,6 +177,9 @@ $(PFM)\$(VARIETY)\finaltest.exe: $(PFM)\$(VARIETY)\finaltest.obj \
$(PFM)\$(VARIETY)\fotest.exe: $(PFM)\$(VARIETY)\fotest.obj \
$(PFM)\$(VARIETY)\mps.lib $(TESTLIBOBJ)
$(PFM)\$(VARIETY)\gcbench.exe: $(PFM)\$(VARIETY)\gcbench.obj \
$(PFM)\$(VARIETY)\mps.lib $(FMTTESTOBJ) $(TESTLIBOBJ)
$(PFM)\$(VARIETY)\landtest.exe: $(PFM)\$(VARIETY)\landtest.obj \
$(PFM)\$(VARIETY)\mps.lib $(TESTLIBOBJ)
@ -179,7 +189,7 @@ $(PFM)\$(VARIETY)\locbwcss.exe: $(PFM)\$(VARIETY)\locbwcss.obj \
$(PFM)\$(VARIETY)\lockcov.exe: $(PFM)\$(VARIETY)\lockcov.obj \
$(PFM)\$(VARIETY)\mps.lib $(TESTLIBOBJ)
$(PFM)\$(VARIETY)\lockutw3.exe: $(PFM)\$(VARIETY)\lockutw3.obj \
$(PFM)\$(VARIETY)\lockut.exe: $(PFM)\$(VARIETY)\lockut.obj \
$(PFM)\$(VARIETY)\mps.lib $(TESTLIBOBJ)
$(PFM)\$(VARIETY)\locusss.exe: $(PFM)\$(VARIETY)\locusss.obj \
@ -306,7 +316,7 @@ $(PFM)\$(VARIETY)\sqlite3.obj:
# C. COPYRIGHT AND LICENSE
#
# Copyright (C) 2001-2013 Ravenbrook Limited <http://www.ravenbrook.com/>.
# Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
# All rights reserved. This is an open source license. Contact
# Ravenbrook for commercial licensing options.
#

View file

@ -58,23 +58,27 @@ TEST_TARGETS=\
airtest.exe \
amcss.exe \
amcsshe.exe \
amcssth.exe \
amsss.exe \
amssshe.exe \
apss.exe \
arenacv.exe \
awlut.exe \
awluthe.exe \
awlutth.exe \
btcv.exe \
bttest.exe \
djbench.exe \
exposet0.exe \
expt825.exe \
finalcv.exe \
finaltest.exe \
fotest.exe \
gcbench.exe \
landtest.exe \
locbwcss.exe \
lockcov.exe \
lockutw3.exe \
lockut.exe \
locusss.exe \
locv.exe \
messtest.exe \
@ -178,7 +182,7 @@ SNC = <poolsnc>
DW = <fmtdy> <fmtno>
FMTTEST = <fmthe> <fmtdy> <fmtno> <fmtdytst>
FMTSCHEME = <fmtscheme>
TESTLIB = <testlib>
TESTLIB = <testlib> <testthrw3> <getoptl>
# CHECK PARAMETERS
@ -226,9 +230,6 @@ TESTLIB = <testlib>
!IFNDEF TESTLIB
!ERROR commpre.nmk: TESTLIB not defined
!ENDIF
!IFNDEF TESTLIB
!ERROR commpre.nmk: TESTLIB not defined
!ENDIF
# DECLARATIONS

View file

@ -231,6 +231,16 @@
#define ATTRIBUTE_NO_SANITIZE_ADDRESS
#endif
/* Attribute for functions that do not return.
* GCC: <http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html>
* Clang: <http://clang.llvm.org/docs/AttributeReference.html#id1>
*/
#if defined(MPS_BUILD_GC) || defined(MPS_BUILD_LL)
#define ATTRIBUTE_NORETURN __attribute__((__noreturn__))
#else
#define ATTRIBUTE_NORETURN
#endif
/* EPVMDefaultSubsequentSegSIZE is a default for the alignment of
* subsequent segments (non-initial at each save level) in EPVM. See
@ -356,6 +366,8 @@
pool to be very heavily used. */
#define CONTROL_EXTEND_BY 4096
#define VM_ARENA_SIZE_DEFAULT ((Size)1 << 20)
/* Stack configuration */

View file

@ -13,13 +13,13 @@
#include "mps.c"
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include "getopt.h"
#include "testlib.h"
#include "testthr.h"
#include <stdio.h> /* fprintf, stderr */
#include <stdlib.h> /* alloca, exit, EXIT_SUCCESS, EXIT_FAILURE */
#include <time.h> /* CLOCKS_PER_SEC, clock */
#define DJMUST(expr) \
do { \
@ -56,6 +56,7 @@ static mps_bool_t zoned = TRUE; /* arena allocates using zones */
\
for (k = 0; k < nblocks; ++k) { \
blocks[k].p = NULL; \
blocks[k].s = 0; \
} \
\
for (j = 0; j < npass; ++j) { \
@ -135,24 +136,14 @@ typedef void *(*dj_t)(void *);
static void weave(dj_t dj)
{
pthread_t *threads = alloca(sizeof(threads[0]) * nthreads);
testthr_t *threads = alloca(sizeof(threads[0]) * nthreads);
unsigned t;
for (t = 0; t < nthreads; ++t) {
int err = pthread_create(&threads[t], NULL, dj, NULL);
if (err != 0) {
fprintf(stderr, "Unable to create thread: %d\n", err);
exit(EXIT_FAILURE);
}
}
for (t = 0; t < nthreads; ++t)
testthr_create(&threads[t], dj, NULL);
for (t = 0; t < nthreads; ++t) {
int err = pthread_join(threads[t], NULL);
if (err != 0) {
fprintf(stderr, "Unable to join thread: %d\n", err);
exit(EXIT_FAILURE);
}
}
for (t = 0; t < nthreads; ++t)
testthr_join(&threads[t], NULL);
}
@ -321,7 +312,8 @@ int main(int argc, char *argv[]) {
argv += optind;
printf("seed: %lu\n", seed);
(void)fflush(stdout);
while (argc > 0) {
for (i = 0; i < sizeof(pools) / sizeof(pools[0]); ++i)
if (strcmp(argv[0], pools[i].name) == 0)

View file

@ -44,13 +44,13 @@ char EventBuffer[EventKindLIMIT][EventBufferSIZE];
char *EventLast[EventKindLIMIT];
/* Pointers to the last even written out of each buffer. */
char *EventWritten[EventKindLIMIT];
static char *EventWritten[EventKindLIMIT];
EventControlSet EventKindControl; /* Bit set used to control output. */
/* A single event structure output once per buffer flush. */
EventEventClockSyncStruct eventClockSyncStruct;
static EventEventClockSyncStruct eventClockSyncStruct;
/* eventClockSync -- Populate and write the clock sync event. */
@ -422,7 +422,7 @@ void EventDump(mps_lib_FILE *stream)
for (kind = 0; kind < EventKindLIMIT; ++kind) {
for (event = (Event)EventLast[kind];
event < (Event)(EventBuffer[kind] + EventBufferSIZE);
(char *)event < EventBuffer[kind] + EventBufferSIZE;
event = (Event)((char *)event + event->any.size)) {
/* Try to keep going even if there's an error, because this is used as a
backtrace and we'll take what we can get. */

View file

@ -197,6 +197,12 @@ static Res eventRead(Bool *eofOut, EventUnion *event, FILE *stream)
return ResIO;
}
if (event->any.size < sizeof(event->any))
return ResFAIL; /* invalid size: too small */
if (event->any.size > sizeof(*event))
return ResFAIL; /* invalid size: too large */
/* Read the rest of the event. */
rest = event->any.size - sizeof(event->any);
if (rest > 0) {

View file

@ -1,6 +1,6 @@
/* <code/eventcom.h> -- Event Logging Common Definitions
*
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
* $Id$
*
* .sources: mps.design.telemetry
@ -56,7 +56,8 @@ ENUM_DECLARE(EventKind)
enum EventDefinitionsEnum {
EVENT_LIST(EVENT_ENUM, X)
EventEnumWarningSuppressor /* suppress comma-at-end-of-enum warning */
/* suppress comma-at-end-of-enum warning */
EventEnumWarningSuppressor = USHRT_MAX
};
@ -89,7 +90,11 @@ typedef Word EventFW; /* word */
typedef unsigned EventFU; /* unsigned integer */
typedef char EventFS[EventStringLengthMAX + sizeof('\0')]; /* string */
typedef double EventFD; /* double */
typedef int EventFB; /* boolean */
/* EventFB must be unsigned (even though Bool is a typedef for int)
* because it used as the type of a bitfield with width 1, and we need
* the legals values of the field to be 0 and 1 (not 0 and -1 which
* would be the case for int : 1). */
typedef unsigned EventFB; /* Boolean */
/* Event packing bitfield specifiers */
#define EventFP_BITFIELD
@ -133,7 +138,7 @@ typedef union EventUnion {
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -102,7 +102,7 @@ typedef sqlite3_int64 int64;
* and for reporting errors.
*/
unsigned int verbosity = 0;
static unsigned int verbosity = 0;
#define LOG_ALWAYS 0
#define LOG_OFTEN 1
@ -533,7 +533,7 @@ static void logFileCompleted(sqlite3 *db,
/* An array of table-creation statement strings. */
const char *createStatements[] = {
static const char *createStatements[] = {
"CREATE TABLE IF NOT EXISTS event_kind (name TEXT,"
" description TEXT,"
" enum INTEGER PRIMARY KEY)",
@ -571,7 +571,7 @@ static void makeTables(sqlite3 *db)
}
}
const char *glueTables[] = {
static const char *glueTables[] = {
"event_kind",
"event_type",
"event_param",

View file

@ -29,15 +29,20 @@
* $Id$
*/
#include "mps.h"
#include "mpsavm.h"
#include "mpscmvff.h"
#include "check.h"
#include "config.h"
#include "eventdef.h"
#include "eventcom.h"
#include "table.h"
#include "testlib.h" /* for ulongest_t and associated print formats */
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdlib.h> /* exit, EXIT_FAILURE, EXIT_SUCCESS */
#include <string.h> /* strcpy, strlen */
static const char *prog; /* program name */
static const char *logFileName = NULL;
@ -106,15 +111,19 @@ static void parseArgs(int argc, char *argv[])
static void *tableAlloc(void *closure, size_t size)
{
UNUSED(closure);
return malloc(size);
mps_pool_t pool = closure;
mps_addr_t p;
mps_res_t res;
res = mps_alloc(&p, pool, size);
if (res != MPS_RES_OK)
everror("allocation failed: %d", res);
return p;
}
static void tableFree(void *closure, void *p, size_t size)
{
UNUSED(closure);
UNUSED(size);
free(p);
mps_pool_t pool = closure;
mps_free(pool, p, size);
}
/* Printing routines */
@ -171,7 +180,7 @@ static double parseDouble(char **pInOut)
#define MAX_STRING_LENGTH 1024
char strBuf[MAX_STRING_LENGTH];
static char strBuf[MAX_STRING_LENGTH];
static char *parseString(char **pInOut)
{
@ -215,21 +224,21 @@ static Table internTable; /* dictionary of intern ids to strings */
static Table labelTable; /* dictionary of addrs to intern ids */
static void createTables(void)
static void createTables(mps_pool_t pool)
{
Res res;
/* MPS intern IDs are serials from zero up, so we can use -1
* and -2 as specials. */
res = TableCreate(&internTable,
(size_t)1<<4,
tableAlloc, tableFree, NULL,
tableAlloc, tableFree, pool,
(Word)-1, (Word)-2);
if (res != ResOK)
everror("Couldn't make intern table.");
/* We assume that 0 and 1 are invalid as Addrs. */
res = TableCreate(&labelTable, (size_t)1<<7,
tableAlloc, tableFree, NULL,
tableAlloc, tableFree, pool,
0, 1);
if (res != ResOK)
everror("Couldn't make label table.");
@ -238,19 +247,19 @@ static void createTables(void)
/* recordIntern -- record an interned string in the table. a copy of
* the string from the parsed buffer into a newly-allocated block. */
static void recordIntern(char *p)
static void recordIntern(mps_pool_t pool, char *p)
{
ulongest_t stringId;
char *string;
char *copy;
mps_addr_t copy;
size_t len;
Res res;
stringId = parseHex(&p);
string = parseString(&p);
len = strlen(string);
copy = malloc(len+1);
if (copy == NULL)
res = mps_alloc(&copy, pool, len + 1);
if (res != MPS_RES_OK)
everror("Couldn't allocate space for a string.");
(void)strcpy(copy, string);
res = TableDefine(internTable, (Word)stringId, (void *)copy);
@ -258,12 +267,55 @@ static void recordIntern(char *p)
everror("Couldn't create an intern mapping.");
}
/* recordLabel records a label (an association between an address and
* a string ID). Note that the event log may have been generated on a
* platform with addresses larger than Word on the current platform.
* If that happens then we are scuppered because our Table code uses
* Word as the key type: there's nothing we can do except detect this
* bad case (see also the EventInit handling and warning code).
/* Over time there may be multiple labels associated with an address,
* so we keep a list, recording for each label the clock when the
* association was made. This means that printAddr can select the
* label that was in force at the time of the event.
*/
typedef struct LabelStruct *Label;
typedef struct LabelStruct {
ulongest_t clock; /* clock of this label */
ulongest_t id; /* string id of this label */
} LabelStruct;
typedef struct LabelListStruct *LabelList;
typedef struct LabelListStruct {
size_t n; /* number of labels in array */
Label labels; /* labels, sorted in order by clock */
} LabelListStruct;
/* labelFind returns the index of the first entry in list with a clock
* value that's greater than 'clock', or list->n if there is no such
* label. The list is assumed to be sorted.
*/
static size_t labelFind(LabelList list, ulongest_t clock)
{
size_t low = 0, high = list->n;
while (low < high) {
size_t mid = (low + high) / 2;
assert(NONNEGATIVE(mid) && mid < list->n);
if (list->labels[mid].clock > clock) {
high = mid;
} else {
low = mid + 1;
}
}
assert(NONNEGATIVE(low) && low <= list->n);
assert(low == list->n || list->labels[low].clock > clock);
return low;
}
/* recordLabel records a label: an association (made at the time given
* by 'clock') between an address and a string ID. These are encoded
* as two hexadecimal numbers in the string pointed to by 'p'.
*
* Note that the event log may have been generated on a platform with
* addresses larger than Word on the current platform. If that happens
* then we are scuppered because our Table code uses Word as the key
* type: there's nothing we can do except detect this bad case (see
* also the EventInit handling and warning code).
*
* We can and do handle the case where string IDs (which are Words on
* the MPS platform) are larger than void* on the current platform.
@ -274,25 +326,50 @@ static void recordIntern(char *p)
* probably a bad idea and maybe doomed to failure.
*/
static void recordLabel(char *p)
static void recordLabel(mps_pool_t pool, ulongest_t clock, char *p)
{
ulongest_t address;
ulongest_t *stringIdP;
LabelList list;
Label newlabels;
mps_addr_t tmp;
size_t pos;
Res res;
address = parseHex(&p);
if (address > (Word)-1) {
(void)printf("label address too large!");
return;
}
stringIdP = malloc(sizeof(ulongest_t));
if (stringIdP == NULL)
everror("Can't allocate space for a string's ID");
*stringIdP = parseHex(&p);
res = TableDefine(labelTable, (Word)address, (void *)stringIdP);
if (TableLookup(&tmp, labelTable, address)) {
list = tmp;
} else {
/* First label for this address */
res = mps_alloc(&tmp, pool, sizeof(LabelListStruct));
if (res != MPS_RES_OK)
everror("Can't allocate space for a label list");
list = tmp;
list->n = 0;
res = TableDefine(labelTable, (Word)address, list);
if (res != ResOK)
everror("Couldn't create a label mapping.");
}
res = mps_alloc(&tmp, pool, sizeof(LabelStruct) * (list->n + 1));
if (res != ResOK)
everror("Couldn't create an intern mapping.");
everror("Couldn't allocate space for list of labels.");
newlabels = tmp;
pos = labelFind(list, clock);
memcpy(newlabels, list->labels, sizeof(LabelStruct) * pos);
newlabels[pos].clock = clock;
newlabels[pos].id = parseHex(&p);
memcpy(newlabels + pos + 1, list->labels + pos,
sizeof(LabelStruct) * (list->n - pos));
if (list->n > 0)
mps_free(pool, list->labels, sizeof(LabelStruct) * list->n);
list->labels = newlabels;
++ list->n;
}
/* output code */
@ -308,20 +385,23 @@ static int hexWordWidth = (MPS_WORD_WIDTH+3)/4;
/* printAddr -- output a ulongest_t in hex, with the interned string
* if the value is in the label table */
static void printAddr(ulongest_t addr, const char *ident)
static void printAddr(ulongest_t clock, ulongest_t addr, const char *ident)
{
ulongest_t label;
void *alias;
void *tmp;
printf("%s:%0*" PRIXLONGEST, ident, hexWordWidth, addr);
if (TableLookup(&alias, labelTable, addr)) {
label = *(ulongest_t*)alias;
putchar('[');
if (TableLookup(&alias, internTable, label))
printStr((char *)alias);
else
printf("unknown label %" PRIuLONGEST, label);
putchar(']');
if (TableLookup(&tmp, labelTable, addr)) {
LabelList list = tmp;
size_t pos = labelFind(list, clock);
if (pos > 0) {
ulongest_t id = list->labels[pos - 1].id;
putchar('[');
if (TableLookup(&tmp, internTable, id))
printStr((char *)tmp);
else
printf("unknown label %" PRIXLONGEST, id);
putchar(']');
}
}
putchar(' ');
}
@ -332,7 +412,7 @@ static void printAddr(ulongest_t addr, const char *ident)
#define processParamA(ident) \
val_hex = parseHex(&p); \
printAddr(val_hex, #ident);
printAddr(clock, val_hex, #ident);
#define processParamP processParamA
#define processParamW processParamA
@ -375,7 +455,7 @@ static const char *eventName[EventCodeMAX+EventCodeMAX];
/* readLog -- read and parse log. Returns the number of events written. */
static void readLog(FILE *input)
static void readLog(mps_pool_t pool, FILE *input)
{
int i;
@ -415,9 +495,9 @@ static void readLog(FILE *input)
/* for a few particular codes, we do local processing. */
if (code == EventInternCode) {
recordIntern(q);
recordIntern(pool, q);
} else if (code == EventLabelCode) {
recordLabel(q);
recordLabel(pool, clock, q);
} else if (code == EventEventInitCode) {
ulongest_t major, median, minor, maxCode, maxNameLen, wordWidth, clocksPerSec;
major = parseHex(&q); /* EVENT_VERSION_MAJOR */
@ -476,6 +556,9 @@ static void readLog(FILE *input)
int main(int argc, char *argv[])
{
mps_arena_t arena;
mps_pool_t pool;
mps_res_t res;
FILE *input;
parseArgs(argc, argv);
@ -488,8 +571,20 @@ int main(int argc, char *argv[])
everror("unable to open %s", logFileName);
}
createTables();
readLog(input);
res = mps_arena_create_k(&arena, mps_arena_class_vm(), mps_args_none);
if (res != MPS_RES_OK)
everror("failed to create arena: %d", res);
res = mps_pool_create_k(&pool, arena, mps_class_mvff(), mps_args_none);
if (res != MPS_RES_OK)
everror("failed to create pool: %d", res);
createTables(pool);
readLog(pool, input);
mps_pool_destroy(pool);
mps_arena_destroy(arena);
(void)fclose(input);
return 0;
}

View file

@ -19,12 +19,9 @@
#include "mpscamc.h"
#include "mpsavm.h"
#include "mpstd.h"
#ifdef MPS_OS_W3
#include "mpsw3.h"
#endif
#include "mps.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h> /* fflush, printf, puts, stdout */
/* These values have been tuned in the hope of getting one dynamic collection. */
@ -75,12 +72,6 @@ static void report(mps_arena_t arena)
printf("not_condemned %"PRIuLONGEST"\n", (ulongest_t)not_condemned);
mps_message_discard(arena, message);
if (condemned > (gen1SIZE + gen2SIZE + (size_t)128) * 1024)
/* When condemned size is larger than could happen in a gen 2
* collection (discounting ramps, natch), guess that was a dynamic
* collection, and reset the commit limit, so it doesn't run out. */
die(mps_arena_commit_limit_set(arena, 2 * testArenaSIZE), "set limit");
}
}
@ -115,15 +106,7 @@ static void test_stepper(mps_addr_t object, mps_fmt_t fmt, mps_pool_t pool,
testlib_unused(fmt);
testlib_unused(pool);
testlib_unused(s);
#ifdef MPS_OS_W3
__try {
dylan_mutate(object);
} __except(EXCEPTION_EXECUTE_HANDLER) {
error("Unexpected exception.\n");
}
#else
dylan_mutate(object);
#endif
(*(unsigned long *)p)++;
}

View file

@ -34,10 +34,8 @@
#include "fmtdy.h"
#include "fmtdytst.h"
#include "mpstd.h"
#ifdef MPS_OS_W3
#include "mpsw3.h"
#endif
#include <stdlib.h>
#include <stdio.h> /* printf, fflush, stdout */
#define testArenaSIZE ((size_t)16<<20)

View file

@ -26,10 +26,8 @@
#include "fmtdy.h"
#include "fmtdytst.h"
#include "mpstd.h"
#ifdef MPS_OS_W3
#include "mpsw3.h"
#endif
#include <stdlib.h>
#include <stdio.h> /* printf */
#define testArenaSIZE ((size_t)16<<20)

View file

@ -22,14 +22,13 @@
#include "mpscamc.h"
#include "mpscams.h"
#include "mpscawl.h"
#include "mpsclo.h"
#include "mpsavm.h"
#include "fmtdy.h"
#include "fmtdytst.h"
#include "mpstd.h"
#ifdef MPS_OS_W3
#include "mpsw3.h"
#endif
#include <stdlib.h>
#include <stdio.h> /* fflush, printf, stdout */
#define testArenaSIZE ((size_t)16<<20)
@ -160,16 +159,16 @@ static void test_trees(const char *name, mps_arena_t arena, mps_ap_t ap,
while (mps_message_poll(arena)) {
mps_message_t message;
mps_addr_t objaddr;
cdie(mps_message_get(&message, arena,
mps_message_type_finalization()),
"get");
cdie(mps_message_get(&message, arena, mps_message_type_finalization()),
"message_get");
mps_message_finalization_ref(&objaddr, arena, message);
mps_message_discard(arena, message);
++ final_this_time;
}
finals += final_this_time;
printf("%"PRIuLONGEST" objects finalized: total %"PRIuLONGEST
" of %"PRIuLONGEST"\n", final_this_time, finals, object_count);
" of %"PRIuLONGEST"\n", (ulongest_t)final_this_time,
(ulongest_t)finals, (ulongest_t)object_count);
}
cdie(finals == object_count, "Not all objects were finalized.");
}
@ -183,6 +182,8 @@ static void *test(mps_arena_t arena, mps_class_t pool_class)
die(mps_fmt_create_A(&fmt, arena, dylan_fmt_A()), "fmt_create\n");
MPS_ARGS_BEGIN(args) {
/* Allocate into generation 0 so that they get finalized quickly. */
MPS_ARGS_ADD(args, MPS_KEY_GEN, 0);
MPS_ARGS_ADD(args, MPS_KEY_FORMAT, fmt);
MPS_ARGS_ADD(args, MPS_KEY_AWL_FIND_DEPENDENT, test_awl_find_dependent);
die(mps_pool_create_k(&pool, arena, pool_class, args),
@ -221,8 +222,10 @@ int main(int argc, char *argv[])
die(mps_thread_reg(&thread, arena), "thread_reg\n");
test(arena, mps_class_amc());
/* TODO: test(arena, mps_class_ams()); */
/* TODO: test(arena, mps_class_awl()); */
test(arena, mps_class_amcz());
test(arena, mps_class_ams());
test(arena, mps_class_awl());
/* TODO: test(arena, mps_class_lo()); */
mps_thread_dereg(thread);
mps_arena_destroy(arena);

View file

@ -73,8 +73,12 @@ mps_res_t dylan_make_wrappers(void)
* If the raw memory is large enough, initialises it to a dylan-vector,
* whose slots are initialised to either dylan-ints, or valid refs, at
* random.
* Caller must supply an array of (at least 1) valid refs to copy, via
* the "refs" and "nr_refs" arguments.
*
* Caller must supply an array of valid refs to copy, via the "refs"
* and "nr_refs" arguments. If "nr_refs" is 0, all slots are
* initialized to dylan-ints: this may be useful for making leaf
* objects.
*
* (Makes a pad if the raw memory is too small to hold a dylan-vector)
*/
@ -100,7 +104,7 @@ mps_res_t dylan_init(mps_addr_t addr, size_t size,
for(i = 0; i < t; ++i) {
mps_word_t r = rnd();
if(r & 1)
if(nr_refs == 0 || (r & 1))
p[2+i] = ((r & ~(mps_word_t)3) | 1); /* random int */
else
p[2+i] = (mps_word_t)refs[(r >> 1) % nr_refs]; /* random ptr */

View file

@ -12,14 +12,8 @@
/* special objects */
obj_t obj_empty; /* (), the empty list */
obj_t obj_eof; /* end of file */
obj_t obj_error; /* error indicator */
obj_t obj_true; /* #t, boolean true */
obj_t obj_false; /* #f, boolean false */
obj_t obj_undefined; /* undefined result indicator */
obj_t obj_tail; /* tail recursion indicator */
obj_t obj_deleted; /* deleted key in hashtable */
static obj_t obj_true; /* #t, boolean true */
static obj_t obj_false; /* #f, boolean false */
/* MPS globals */

View file

@ -28,7 +28,7 @@
#include "mpmtypes.h"
#include "poolmfs.h"
#include <stdarg.h>
#include <stdio.h> /* printf */
#define testArenaSIZE ((((size_t)3)<<24) - 4)
@ -181,7 +181,7 @@ int main(int argc, char *argv[])
die(mps_arena_create(&arena, mps_arena_class_vm(), testArenaSIZE),
"mps_arena_create");
alignment = (1 << (rnd() % 4)) * MPS_PF_ALIGN;
alignment = sizeof(void *) << (rnd() % 4);
MPS_ARGS_BEGIN(args) {
MPS_ARGS_ADD(args, MPS_KEY_EXTEND_BY, (64 + rnd() % 64) * 1024);
MPS_ARGS_ADD(args, MPS_KEY_MEAN_SIZE, (1 + rnd() % 8) * 8);
@ -200,7 +200,7 @@ int main(int argc, char *argv[])
die(mps_arena_create(&arena, mps_arena_class_vm(), testArenaSIZE),
"mps_arena_create");
alignment = (1 << (rnd() % 4)) * MPS_PF_ALIGN;
alignment = sizeof(void *) << (rnd() % 4);
MPS_ARGS_BEGIN(args) {
MPS_ARGS_ADD(args, MPS_KEY_ALIGN, alignment);
MPS_ARGS_ADD(args, MPS_KEY_MIN_SIZE, (1 + rnd() % 4) * 4);

View file

@ -7,18 +7,16 @@
*/
#include "mps.c"
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include "getopt.h"
#include "testlib.h"
#include "testthr.h"
#include "fmtdy.h"
#include "fmtdytst.h"
#include <stdio.h> /* fprintf, printf, putchars, sscanf, stderr, stdout */
#include <stdlib.h> /* alloca, exit, EXIT_FAILURE, EXIT_SUCCESS, strtoul */
#include <time.h> /* clock, CLOCKS_PER_SEC */
#define RESMUST(expr) \
do { \
mps_res_t res = (expr); \
@ -56,7 +54,7 @@ typedef struct gcthread_s *gcthread_t;
typedef void *(*gcthread_fn_t)(gcthread_t thread);
struct gcthread_s {
pthread_t pthread;
testthr_t thread;
mps_thr_t mps_thread;
mps_root_t reg_root;
mps_ap_t ap;
@ -189,23 +187,12 @@ static void weave(gcthread_fn_t fn)
for (t = 0; t < nthreads; ++t) {
gcthread_t thread = &threads[t];
int err;
thread->fn = fn;
err = pthread_create(&thread->pthread, NULL, start, thread);
if (err != 0) {
fprintf(stderr, "Unable to create thread: %d\n", err);
exit(EXIT_FAILURE);
}
testthr_create(&thread->thread, start, thread);
}
for (t = 0; t < nthreads; ++t) {
gcthread_t thread = &threads[t];
int err = pthread_join(thread->pthread, NULL);
if (err != 0) {
fprintf(stderr, "Unable to join thread: %d\n", err);
exit(EXIT_FAILURE);
}
}
for (t = 0; t < nthreads; ++t)
testthr_join(&threads[t].thread, NULL);
}
static void weave1(gcthread_fn_t fn)
@ -331,8 +318,8 @@ int main(int argc, char *argv[]) {
double mort = 0.0;
cap = (size_t)strtoul(optarg, &p, 10);
switch(toupper(*p)) {
case 'G': cap *= 1024; /* fall through */
case 'M': cap *= 1024; /* fall through */
case 'G': cap <<= 20; p++; break;
case 'M': cap <<= 10; p++; break;
case 'K': p++; break;
default: cap = 0; break;
}
@ -353,9 +340,9 @@ int main(int argc, char *argv[]) {
char *p;
arenasize = (unsigned)strtoul(optarg, &p, 10);
switch(toupper(*p)) {
case 'G': arenasize *= 1024;
case 'M': arenasize *= 1024;
case 'K': arenasize *= 1024; break;
case 'G': arenasize <<= 30; break;
case 'M': arenasize <<= 20; break;
case 'K': arenasize <<= 10; break;
case '\0': break;
default:
fprintf(stderr, "Bad arena size %s\n", optarg);
@ -432,7 +419,8 @@ int main(int argc, char *argv[]) {
argv += optind;
printf("seed: %lu\n", seed);
(void)fflush(stdout);
while (argc > 0) {
for (i = 0; i < sizeof(pools) / sizeof(pools[0]); ++i)
if (strcmp(argv[0], pools[i].name) == 0)

View file

@ -48,8 +48,6 @@
#ifndef _GETOPT_H_
#define _GETOPT_H_
#include <sys/cdefs.h>
/*
* GNU-like getopt_long()/getopt_long_only() with 4.4BSD optreset extension.
* getopt() is declared here too for GNU programs.
@ -72,7 +70,6 @@ struct option {
int val;
};
__BEGIN_DECLS
int getopt_long(int, char * const *, const char *,
const struct option *, int *);
int getopt_long_only(int, char * const *, const char *,
@ -88,6 +85,5 @@ extern int optind, opterr, optopt;
#define _OPTRESET_DECLARED
extern int optreset; /* getopt(3) external variable */
#endif
__END_DECLS
#endif /* !_GETOPT_H_ */

View file

@ -397,25 +397,7 @@ void GlobalsFinish(Globals arenaGlobals)
Arena arena;
Rank rank;
/* Check that the tear-down is complete: that the client has
* destroyed all data structures associated with the arena. We do
* this *before* calling AVERT(Globals, arenaGlobals) because the
* AVERT will crash if there are any remaining data structures, and
* it is politer to assert than to crash. (The crash would happen
* because by this point in the code the control pool has been
* destroyed and so the address space containing all these rings has
* potentially been unmapped, and so RingCheck dereferences a
* pointer into that unmapped memory.) See job000652. */
arena = GlobalsArena(arenaGlobals);
AVER(RingIsSingle(&arena->formatRing));
AVER(RingIsSingle(&arena->chainRing));
AVER(RingIsSingle(&arena->messageRing));
AVER(RingIsSingle(&arena->threadRing));
for(rank = 0; rank < RankLIMIT; ++rank)
AVER(RingIsSingle(&arena->greyRing[rank]));
AVER(RingIsSingle(&arenaGlobals->poolRing));
AVER(RingIsSingle(&arenaGlobals->rootRing));
AVERT(Globals, arenaGlobals);
STATISTIC_STAT(EVENT2(ArenaWriteFaults, arena,
@ -445,6 +427,7 @@ void GlobalsPrepareToDestroy(Globals arenaGlobals)
TraceId ti;
Trace trace;
Chain defaultChain;
Rank rank;
AVERT(Globals, arenaGlobals);
@ -499,6 +482,31 @@ void GlobalsPrepareToDestroy(Globals arenaGlobals)
arena->finalPool = NULL;
PoolDestroy(pool);
}
/* Check that the tear-down is complete: that the client has
* destroyed all data structures associated with the arena. We do
* this here rather than in GlobalsFinish because by the time that
* is called, the control pool has been destroyed and so the address
* space containing all these rings has potentially been unmapped,
* and so RingCheck dereferences a pointer into that unmapped memory
* and we get a crash instead of an assertion. See job000652.
*/
AVER(RingIsSingle(&arena->formatRing));
AVER(RingIsSingle(&arena->chainRing));
AVER(RingIsSingle(&arena->messageRing));
AVER(RingIsSingle(&arena->threadRing));
AVER(RingIsSingle(&arenaGlobals->rootRing));
for(rank = 0; rank < RankLIMIT; ++rank)
AVER(RingIsSingle(&arena->greyRing[rank]));
/* At this point the following pools still exist:
* 0. arena->freeCBSBlockPoolStruct
* 1. arena->reservoirStruct
* 2. arena->controlPoolStruct
* 3. arena->controlPoolStruct.blockPoolStruct
* 4. arena->controlPoolStruct.spanPoolStruct
*/
AVER(RingLength(&arenaGlobals->poolRing) == 5);
}
@ -617,6 +625,7 @@ void ArenaLeaveRecursive(Arena arena)
* version. The format is platform-specific. We won't necessarily
* publish this. */
extern MutatorFaultContext mps_exception_info;
MutatorFaultContext mps_exception_info = NULL;
@ -1131,7 +1140,7 @@ void ArenaSetEmergency(Arena arena, Bool emergency)
AVERT(Arena, arena);
AVERT(Bool, emergency);
EVENT2(ArenaSetEmergency, arena, emergency);
EVENT2(ArenaSetEmergency, arena, BOOL(emergency));
arena->emergency = emergency;
}

View file

@ -26,9 +26,7 @@
#include "poolmfs.h"
#include "testlib.h"
#include <stdarg.h>
#include <stdlib.h>
#include <time.h>
#include <stdio.h> /* printf */
SRCID(landtest, "$Id$");

View file

@ -17,10 +17,13 @@ CFLAGSCOMPILER := \
-Waggregate-return \
-Wall \
-Wcast-qual \
-Wconversion \
-Wduplicate-enum \
-Werror \
-Wextra \
-Winline \
-Wmissing-prototypes \
-Wmissing-variable-declarations \
-Wnested-externs \
-Wno-extended-offsetof \
-Wpointer-arith \

View file

@ -11,8 +11,7 @@
#include "mpslib.h"
#include "mps.h"
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h> /* printf */
/* some constants */

View file

@ -4,19 +4,37 @@
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*/
#include "mps.h"
#include "mpsavm.h"
#include "mpscmfs.h"
#include "mpm.h"
#include "testlib.h"
#include "mpslib.h"
#include <stdlib.h> /* for malloc & free */
#include <stdio.h> /* printf */
int main(int argc, char *argv[])
{
Lock a = malloc(LockSize());
Lock b = malloc(LockSize());
mps_arena_t arena;
mps_pool_t pool;
mps_addr_t p;
Lock a, b;
testlib_init(argc, argv);
die(mps_arena_create_k(&arena, mps_arena_class_vm(), mps_args_none),
"arena_create");
MPS_ARGS_BEGIN(args) {
MPS_ARGS_ADD(args, MPS_KEY_MFS_UNIT_SIZE, LockSize());
die(mps_pool_create_k(&pool, arena, mps_class_mfs(), args), "pool_create");
} MPS_ARGS_END(args);
die(mps_alloc(&p, pool, LockSize()), "alloc a");
a = p;
die(mps_alloc(&p, pool, LockSize()), "alloc b");
b = p;
Insist(a != NULL);
Insist(b != NULL);
@ -44,8 +62,11 @@ int main(int argc, char *argv[])
LockReleaseMPM(a);
LockFinish(a);
LockReleaseGlobalRecursive();
free(a);
free(b);
mps_free(pool, a, LockSize());
mps_free(pool, b, LockSize());
mps_pool_destroy(pool);
mps_arena_destroy(arena);
printf("%s: Conclusion: Failed to find any defects.\n", argv[0]);
return 0;

View file

@ -1,30 +1,26 @@
/* lockutw3.c: LOCK UTILIZATION TEST
/* lockut.c: LOCK UTILIZATION TEST
*
* $Id$
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*/
#include <stdlib.h> /* malloc */
#include "mps.h"
#include "mpsavm.h"
#include "mpscmfs.h"
#include "mpm.h"
#include "testlib.h"
#include "mpslib.h"
#include "testthr.h"
#include "mpswin.h"
#ifndef MPS_OS_W3
#error "Relies on Win32 threads"
#endif
#include <stdio.h> /* printf */
#define nTHREADS 4
static Lock lock;
unsigned long shared, tmp;
static unsigned long shared, tmp;
void incR(unsigned long i)
static void incR(unsigned long i)
{
LockClaimRecursive(lock);
if (i < 100) {
@ -40,7 +36,7 @@ void incR(unsigned long i)
}
void inc(unsigned long i)
static void inc(unsigned long i)
{
incR( (i+1) >>1);
i >>= 1;
@ -59,23 +55,33 @@ void inc(unsigned long i)
#define COUNT 100000l
DWORD WINAPI thread0(void *p)
static void *thread0(void *p)
{
(void)p;
testlib_unused(p);
inc(COUNT);
return 0;
return NULL;
}
int main(int argc, char *argv[])
{
DWORD id;
HANDLE t[10];
mps_arena_t arena;
mps_pool_t pool;
mps_addr_t p;
testthr_t t[10];
unsigned i;
testlib_init(argc, argv);
lock = malloc(LockSize());
die(mps_arena_create_k(&arena, mps_arena_class_vm(), mps_args_none),
"arena_create");
MPS_ARGS_BEGIN(args) {
MPS_ARGS_ADD(args, MPS_KEY_MFS_UNIT_SIZE, LockSize());
die(mps_pool_create_k(&pool, arena, mps_class_mfs(), args), "pool_create");
} MPS_ARGS_END(args);
die(mps_alloc(&p, pool, LockSize()), "alloc");
lock = p;
Insist(lock != NULL);
LockInit(lock);
@ -84,17 +90,19 @@ int main(int argc, char *argv[])
shared = 0;
for(i = 0; i < nTHREADS; i++)
t[i] = CreateThread(NULL, 0, thread0, NULL, 0, &id);
testthr_create(&t[i], thread0, NULL);
for(i = 0; i < nTHREADS; i++) {
cdie(WaitForSingleObject(t[i], INFINITE) == WAIT_OBJECT_0,
"WaitForSingleObject");
}
for(i = 0; i < nTHREADS; i++)
testthr_join(&t[i], NULL);
Insist(shared == nTHREADS*COUNT);
LockFinish(lock);
mps_free(pool, lock, LockSize());
mps_pool_destroy(pool);
mps_arena_destroy(arena);
printf("%s: Conclusion: Failed to find any defects.\n", argv[0]);
return 0;
}

View file

@ -12,8 +12,7 @@
#include "mpslib.h"
#include "mps.h"
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h> /* printf */
/* some constants */

View file

@ -13,6 +13,8 @@
#include "mpsclo.h"
#include "mpsavm.h"
#include <stdio.h> /* printf */
#define testArenaSIZE ((size_t)16<<20)

View file

@ -10,8 +10,7 @@
#include "testlib.h"
#include "mpslib.h"
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h> /* printf */
SRCID(messtest, "$Id$");

View file

@ -1,7 +1,7 @@
/* meter.h: METER INTERFACE
*
* $Id$
* Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
* .sources: mps.design.metrics.
*
@ -45,9 +45,12 @@ extern void MeterEmit(Meter meter);
#define METER_ACC(meter, delta) \
STATISTIC(MeterAccumulate(&(meter), delta))
#if defined(STATISTICS)
#define METER_WRITE(meter, stream) MeterWrite(&(meter), stream)
#define METER_WRITE(meter, stream) BEGIN \
Res _res = MeterWrite(&(meter), (stream)); \
if (_res != ResOK) return _res; \
END
#elif defined(STATISTICS_NONE)
#define METER_WRITE(meter, stream) (ResOK)
#define METER_WRITE(meter, stream) NOOP
#else
#error "No statistics configured."
#endif
@ -59,7 +62,7 @@ extern void MeterEmit(Meter meter);
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2013 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -1,7 +1,7 @@
/* misc.h: MISCELLANEOUS DEFINITIONS
*
* $Id$
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
* Portions copyright (C) 2001 Global Graphics Software.
*
* Small general things which are useful for C but aren't part of the
@ -50,6 +50,7 @@ typedef const struct SrcIdStruct {
#define SRCID(id, scmid) \
static SrcIdStruct id ## FileSrcIdStruct = \
{__FILE__, (scmid), __DATE__, __TIME__}; \
extern SrcId id ## SrcId; \
SrcId id ## SrcId = &id ## FileSrcIdStruct
@ -170,6 +171,16 @@ typedef const struct SrcIdStruct {
((type *)(void *)((char *)(p) - offsetof(type, field)))
/* BITFIELD -- coerce a value into a bitfield
*
* This coerces value to the given width and type in a way that avoids
* warnings from gcc -Wconversion about possible loss of data.
*/
#define BITFIELD(type, value, width) ((type)value & (((type)1 << (width)) - 1))
#define BOOL(v) BITFIELD(unsigned, (v), 1)
/* Bit Sets -- sets of integers in [0,N-1].
*
* Can be used on any unsigned integral type, ty. These definitions
@ -191,6 +202,7 @@ typedef const struct SrcIdStruct {
#define BS_SUB(s1, s2) BS_SUPER((s2), (s1))
#define BS_IS_SINGLE(s) ( ((s) != 0) && (((s) & ((s)-1)) == 0) )
#define BS_SYM_DIFF(s1, s2) ((s1) ^ (s2))
#define BS_BITFIELD(ty, s) BITFIELD(ty ## Set, (s), ty ## LIMIT)
#endif /* misc_h */
@ -198,7 +210,7 @@ typedef const struct SrcIdStruct {
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -174,16 +174,16 @@ Word (WordAlignDown)(Word word, Align alignment)
/* SizeIsP2 -- test whether a size is a power of two */
Bool SizeIsP2(Size size)
Bool (SizeIsP2)(Size size)
{
return WordIsP2((Word)size);
return SizeIsP2(size);
}
/* WordIsP2 -- tests whether a word is a power of two */
Bool WordIsP2(Word word)
Bool (WordIsP2)(Word word)
{
return word > 0 && (word & (word - 1)) == 0;
return WordIsP2(word);
}

View file

@ -143,11 +143,13 @@ extern Bool ResIsAllocFailure(Res res);
* SizeFloorLog2 returns the floor of the logarithm in base 2 of size.
* size can be any positive non-zero value. */
extern Bool SizeIsP2(Size size);
extern Bool (SizeIsP2)(Size size);
#define SizeIsP2(size) WordIsP2((Word)size)
extern Shift SizeLog2(Size size);
extern Shift SizeFloorLog2(Size size);
extern Bool WordIsP2(Word word);
extern Bool (WordIsP2)(Word word);
#define WordIsP2(word) ((word) > 0 && ((word) & ((word) - 1)) == 0)
/* Formatted Output -- see <design/writef/>, <code/mpm.c> */
@ -709,10 +711,10 @@ extern Addr (SegLimit)(Seg seg);
#define SegSummary(seg) (((GCSeg)(seg))->summary)
#define SegSetPM(seg, mode) ((void)((seg)->pm = (mode)))
#define SegSetSM(seg, mode) ((void)((seg)->sm = (mode)))
#define SegSetDepth(seg, d) ((void)((seg)->depth = (d)))
#define SegSetNailed(seg, ts) ((void)((seg)->nailed = (ts)))
#define SegSetPM(seg, mode) ((void)((seg)->pm = BS_BITFIELD(Access, (mode))))
#define SegSetSM(seg, mode) ((void)((seg)->sm = BS_BITFIELD(Access, (mode))))
#define SegSetDepth(seg, d) ((void)((seg)->depth = BITFIELD(unsigned, (d), ShieldDepthWIDTH)))
#define SegSetNailed(seg, ts) ((void)((seg)->nailed = BS_BITFIELD(Trace, (ts))))
/* Buffer Interface -- see <code/buffer.c> */

View file

@ -7,19 +7,14 @@
#include "mpscmv.h"
#include "mpscmvff.h"
#include "mpscmfs.h"
#include "mpslib.h"
#include "mpsavm.h"
#include "testlib.h"
#include "mpslib.h"
#include "mps.h"
#include <stdlib.h>
#include <stdarg.h>
/* TODO: Decide whether we should support the MPS pool class externally,
create mpscmfs.h, and replace this extern with proper use of its
interface. */
extern mps_class_t PoolClassMFS(void);
#include <stdio.h> /* printf */
#define testArenaSIZE ((((size_t)64)<<20) - 4)
@ -156,8 +151,7 @@ static void testInArena(mps_arena_t arena, mps_pool_debug_option_s *options)
printf("MFS\n");
fixedSizeSize = 13;
die(stress(PoolClassMFS(),
fixedSize, arena, (size_t)100000, fixedSizeSize),
die(stress(mps_class_mfs(), fixedSize, arena, (size_t)100000, fixedSizeSize),
"stress MFS");
printf("MV\n");

View file

@ -1,7 +1,7 @@
/* mpmst.h: MEMORY POOL MANAGER DATA STRUCTURES
*
* $Id$
* Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
* Portions copyright (C) 2001 Global Graphics Software.
*
* .design: This header file crosses module boundaries. The relevant
@ -275,8 +275,8 @@ typedef struct SegStruct { /* segment structure */
RingStruct poolRing; /* link in list of segs in pool */
Addr limit; /* limit of segment */
unsigned depth : ShieldDepthWIDTH; /* see <code/shield.c#def.depth> */
AccessSet pm : AccessSetWIDTH; /* protection mode, <code/shield.c> */
AccessSet sm : AccessSetWIDTH; /* shield mode, <code/shield.c> */
AccessSet pm : AccessLIMIT; /* protection mode, <code/shield.c> */
AccessSet sm : AccessLIMIT; /* shield mode, <code/shield.c> */
TraceSet grey : TraceLIMIT; /* traces for which seg is grey */
TraceSet white : TraceLIMIT; /* traces for which seg is white */
TraceSet nailed : TraceLIMIT; /* traces for which seg has nailed objects */
@ -817,7 +817,7 @@ typedef struct AllocPatternStruct {
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2013 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -287,7 +287,7 @@ typedef Res (*LandDescribeMethod)(Land land, mps_lib_FILE *stream);
#define AccessSetEMPTY ((AccessSet)0) /* <design/type/#access-set> */
#define AccessREAD ((AccessSet)(1<<0))
#define AccessWRITE ((AccessSet)(1<<1))
#define AccessSetWIDTH (2)
#define AccessLIMIT (2)
#define RefSetEMPTY BS_EMPTY(RefSet)
#define RefSetUNIV BS_UNIV(RefSet)
#define ZoneSetEMPTY BS_EMPTY(ZoneSet)

View file

@ -50,6 +50,7 @@
3114A65B156E95B4001E0AA3 /* PBXTargetDependency */,
2231BB6D18CA986B002D6322 /* PBXTargetDependency */,
31D60034156D3D5A00337B26 /* PBXTargetDependency */,
2286E4C918F4389E004111E2 /* PBXTargetDependency */,
2231BB6F18CA986D002D6322 /* PBXTargetDependency */,
3114A5A0156E915A001E0AA3 /* PBXTargetDependency */,
3114A6A7156E9739001E0AA3 /* PBXTargetDependency */,
@ -88,6 +89,10 @@
224CC793175E1821002FF81B /* libmps.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 31EEABFB156AAF9D00714D05 /* libmps.a */; };
224CC79F175E321C002FF81B /* mv2test.c in Sources */ = {isa = PBXBuildFile; fileRef = 3114A686156E9674001E0AA3 /* mv2test.c */; };
224CC7A0175E322C002FF81B /* fotest.c in Sources */ = {isa = PBXBuildFile; fileRef = 224CC79E175E3202002FF81B /* fotest.c */; };
22561A9818F4265D00372C66 /* testthrix.c in Sources */ = {isa = PBXBuildFile; fileRef = 22561A9718F4263300372C66 /* testthrix.c */; };
22561A9918F4266600372C66 /* testthrix.c in Sources */ = {isa = PBXBuildFile; fileRef = 22561A9718F4263300372C66 /* testthrix.c */; };
22561A9A18F426BB00372C66 /* testthrix.c in Sources */ = {isa = PBXBuildFile; fileRef = 22561A9718F4263300372C66 /* testthrix.c */; };
22561A9B18F426F300372C66 /* testthrix.c in Sources */ = {isa = PBXBuildFile; fileRef = 22561A9718F4263300372C66 /* testthrix.c */; };
2291A5B1175CAB2F001D4920 /* fmtdy.c in Sources */ = {isa = PBXBuildFile; fileRef = 3124CAC6156BE48D00753214 /* fmtdy.c */; };
2291A5B2175CAB2F001D4920 /* fmtdytst.c in Sources */ = {isa = PBXBuildFile; fileRef = 3124CAC7156BE48D00753214 /* fmtdytst.c */; };
2291A5B3175CAB2F001D4920 /* fmthe.c in Sources */ = {isa = PBXBuildFile; fileRef = 3124CAE4156BE6D500753214 /* fmthe.c */; };
@ -113,6 +118,10 @@
22C2ACA718BE400A006B3677 /* testlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 31EEAC9E156AB73400714D05 /* testlib.c */; };
22C2ACA918BE400A006B3677 /* libmps.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 31EEABFB156AAF9D00714D05 /* libmps.a */; };
22C2ACB018BE4049006B3677 /* nailboardtest.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C2ACA018BE3FEC006B3677 /* nailboardtest.c */; };
22F846B518F437B900982BA7 /* testlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 31EEAC9E156AB73400714D05 /* testlib.c */; };
22F846B718F437B900982BA7 /* libmps.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 31EEABFB156AAF9D00714D05 /* libmps.a */; };
22F846BE18F437D700982BA7 /* lockut.c in Sources */ = {isa = PBXBuildFile; fileRef = 22F846AF18F4379C00982BA7 /* lockut.c */; };
22F846BF18F437E000982BA7 /* testthrix.c in Sources */ = {isa = PBXBuildFile; fileRef = 22561A9718F4263300372C66 /* testthrix.c */; };
22FA176916E8D6FC0098B23F /* fmtdy.c in Sources */ = {isa = PBXBuildFile; fileRef = 3124CAC6156BE48D00753214 /* fmtdy.c */; };
22FA176A16E8D6FC0098B23F /* fmtdytst.c in Sources */ = {isa = PBXBuildFile; fileRef = 3124CAC7156BE48D00753214 /* fmtdytst.c */; };
22FA176B16E8D6FC0098B23F /* fmthe.c in Sources */ = {isa = PBXBuildFile; fileRef = 3124CAE4156BE6D500753214 /* fmthe.c */; };
@ -327,6 +336,13 @@
remoteGlobalIDString = 2D604B9B16514B1A003AAF46;
remoteInfo = mpseventtxt;
};
2286E4C818F4389E004111E2 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 31EEABDA156AAE9E00714D05 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 22F846B018F437B900982BA7;
remoteInfo = lockut;
};
2291A5AE175CAB2F001D4920 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 31EEABDA156AAE9E00714D05 /* Project object */;
@ -418,6 +434,13 @@
remoteGlobalIDString = 3104AFF1156D37A0000A585A;
remoteInfo = all;
};
22F846B218F437B900982BA7 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 31EEABDA156AAE9E00714D05 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 31EEABFA156AAF9D00714D05;
remoteInfo = mps;
};
22FA176616E8D6FC0098B23F /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 31EEABDA156AAE9E00714D05 /* Project object */;
@ -955,6 +978,15 @@
);
runOnlyForDeploymentPostprocessing = 1;
};
22F846B818F437B900982BA7 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = /usr/share/man/man1/;
dstSubfolderSpec = 0;
files = (
);
runOnlyForDeploymentPostprocessing = 1;
};
22FA177016E8D6FC0098B23F /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
@ -1297,6 +1329,8 @@
2231BB6918CA983C002D6322 /* locusss.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = locusss.c; sourceTree = "<group>"; };
224CC799175E1821002FF81B /* fotest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = fotest; sourceTree = BUILT_PRODUCTS_DIR; };
224CC79E175E3202002FF81B /* fotest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = fotest.c; sourceTree = "<group>"; };
22561A9618F4263300372C66 /* testthr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = testthr.h; sourceTree = "<group>"; };
22561A9718F4263300372C66 /* testthrix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testthrix.c; sourceTree = "<group>"; };
2291A5A8175CAA51001D4920 /* poolmv2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = poolmv2.h; sourceTree = "<group>"; };
2291A5A9175CAA9B001D4920 /* awlutth.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = awlutth.c; sourceTree = "<group>"; };
2291A5AA175CAA9B001D4920 /* exposet0.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = exposet0.c; sourceTree = "<group>"; };
@ -1317,6 +1351,8 @@
22C2ACAF18BE400A006B3677 /* nailboardtest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = nailboardtest; sourceTree = BUILT_PRODUCTS_DIR; };
22E30E821886FF1400D98EA9 /* nailboard.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nailboard.c; sourceTree = "<group>"; };
22E30E831886FF1400D98EA9 /* nailboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nailboard.h; sourceTree = "<group>"; };
22F846AF18F4379C00982BA7 /* lockut.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lockut.c; sourceTree = "<group>"; };
22F846BD18F437B900982BA7 /* lockut */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = lockut; sourceTree = BUILT_PRODUCTS_DIR; };
22C5C99A18EC6AEC004C63D4 /* failover.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = failover.c; sourceTree = "<group>"; };
22C5C99B18EC6AEC004C63D4 /* failover.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = failover.h; sourceTree = "<group>"; };
22C5C99C18EC6AEC004C63D4 /* land.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = land.c; sourceTree = "<group>"; };
@ -1331,8 +1367,6 @@
22FACED5188807FF000FDBC1 /* fmtno.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fmtno.h; sourceTree = "<group>"; };
22FACED6188807FF000FDBC1 /* fmtscheme.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = fmtscheme.c; sourceTree = "<group>"; };
22FACED7188807FF000FDBC1 /* fmtscheme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fmtscheme.h; sourceTree = "<group>"; };
22FACED8188807FF000FDBC1 /* locbwcss.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = locbwcss.c; sourceTree = "<group>"; };
22FACED9188807FF000FDBC1 /* locusss.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = locusss.c; sourceTree = "<group>"; };
22FACEDA1888088A000FDBC1 /* ss.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ss.c; sourceTree = "<group>"; };
22FACEDB188808D5000FDBC1 /* mpscmfs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mpscmfs.h; sourceTree = "<group>"; };
22FACEDC18880933000FDBC1 /* poolmfs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = poolmfs.h; sourceTree = "<group>"; };
@ -1670,6 +1704,14 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
22F846B618F437B900982BA7 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
22F846B718F437B900982BA7 /* libmps.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
22FA176E16E8D6FC0098B23F /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@ -2087,6 +2129,7 @@
3124CAB3156BE1B700753214 /* Tests */ = {
isa = PBXGroup;
children = (
22F846AF18F4379C00982BA7 /* lockut.c */,
3114A63D156E94EA001E0AA3 /* abqtest.c */,
22FACED1188807FF000FDBC1 /* airtest.c */,
3124CAF5156BE81100753214 /* amcss.c */,
@ -2134,6 +2177,8 @@
3114A628156E949A001E0AA3 /* teletest.c */,
31EEAC9E156AB73400714D05 /* testlib.c */,
2291A5F0175CB7A4001D4920 /* testlib.h */,
22561A9618F4263300372C66 /* testthr.h */,
22561A9718F4263300372C66 /* testthrix.c */,
3114A6BA156E9768001E0AA3 /* walkt0.c */,
31D6005E156D3F4A00337B26 /* zcoll.c */,
31D6007B156D3FCC00337B26 /* zmess.c */,
@ -2227,6 +2272,7 @@
2231BB6718CA97DC002D6322 /* locusss */,
22FACEED18880983000FDBC1 /* airtest */,
22C2ACAF18BE400A006B3677 /* nailboardtest */,
22F846BD18F437B900982BA7 /* lockut */,
);
name = Products;
sourceTree = "<group>";
@ -2558,6 +2604,24 @@
productReference = 22C2ACAF18BE400A006B3677 /* nailboardtest */;
productType = "com.apple.product-type.tool";
};
22F846B018F437B900982BA7 /* lockut */ = {
isa = PBXNativeTarget;
buildConfigurationList = 22F846B918F437B900982BA7 /* Build configuration list for PBXNativeTarget "lockut" */;
buildPhases = (
22F846B318F437B900982BA7 /* Sources */,
22F846B618F437B900982BA7 /* Frameworks */,
22F846B818F437B900982BA7 /* CopyFiles */,
);
buildRules = (
);
dependencies = (
22F846B118F437B900982BA7 /* PBXTargetDependency */,
);
name = lockut;
productName = lockcov;
productReference = 22F846BD18F437B900982BA7 /* lockut */;
productType = "com.apple.product-type.tool";
};
22FA176416E8D6FC0098B23F /* amcssth */ = {
isa = PBXNativeTarget;
buildConfigurationList = 22FA177116E8D6FC0098B23F /* Build configuration list for PBXNativeTarget "amcssth" */;
@ -3284,6 +3348,7 @@
2231BB4C18CA97D8002D6322 /* locbwcss */,
31D60026156D3D3E00337B26 /* lockcov */,
2231BB5A18CA97DC002D6322 /* locusss */,
22F846B018F437B900982BA7 /* lockut */,
3114A58F156E913C001E0AA3 /* locv */,
3114A694156E971B001E0AA3 /* messtest */,
31EEAC64156AB52600714D05 /* mpmss */,
@ -3363,6 +3428,7 @@
2291A5B3175CAB2F001D4920 /* fmthe.c in Sources */,
2291A5B4175CAB2F001D4920 /* fmtno.c in Sources */,
2291A5B5175CAB2F001D4920 /* testlib.c in Sources */,
22561A9918F4266600372C66 /* testthrix.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -3408,6 +3474,16 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
22F846B318F437B900982BA7 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
22F846BE18F437D700982BA7 /* lockut.c in Sources */,
22F846B518F437B900982BA7 /* testlib.c in Sources */,
22F846BF18F437E000982BA7 /* testthrix.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
22FA176716E8D6FC0098B23F /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@ -3418,6 +3494,7 @@
22FA176B16E8D6FC0098B23F /* fmthe.c in Sources */,
22FA176C16E8D6FC0098B23F /* fmtno.c in Sources */,
22FA176D16E8D6FC0098B23F /* testlib.c in Sources */,
22561A9818F4265D00372C66 /* testthrix.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -3694,6 +3771,7 @@
318DA8D31892B27E0089718C /* testlib.c in Sources */,
6313D47318A4028E00EB03EF /* djbench.c in Sources */,
318DA8D21892B13B0089718C /* getoptl.c in Sources */,
22561A9A18F426BB00372C66 /* testthrix.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -3801,6 +3879,7 @@
6313D47518A40C6300EB03EF /* fmtdytst.c in Sources */,
6313D47618A40C7B00EB03EF /* fmtdy.c in Sources */,
6313D46A18A400B200EB03EF /* getoptl.c in Sources */,
22561A9B18F426F300372C66 /* testthrix.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -3842,6 +3921,11 @@
target = 2D604B9B16514B1A003AAF46 /* mpseventtxt */;
targetProxy = 2275798816C5422900B662B0 /* PBXContainerItemProxy */;
};
2286E4C918F4389E004111E2 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 22F846B018F437B900982BA7 /* lockut */;
targetProxy = 2286E4C818F4389E004111E2 /* PBXContainerItemProxy */;
};
2291A5AD175CAB2F001D4920 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 31EEABFA156AAF9D00714D05 /* mps */;
@ -3907,6 +3991,11 @@
target = 3104AFF1156D37A0000A585A /* all */;
targetProxy = 22CDE92D16E9EB9300366D0A /* PBXContainerItemProxy */;
};
22F846B118F437B900982BA7 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 31EEABFA156AAF9D00714D05 /* mps */;
targetProxy = 22F846B218F437B900982BA7 /* PBXContainerItemProxy */;
};
22FA176516E8D6FC0098B23F /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 31EEABFA156AAF9D00714D05 /* mps */;
@ -4410,6 +4499,27 @@
};
name = Release;
};
22F846BA18F437B900982BA7 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
PRODUCT_NAME = lockut;
};
name = Debug;
};
22F846BB18F437B900982BA7 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
PRODUCT_NAME = lockut;
};
name = Release;
};
22F846BC18F437B900982BA7 /* RASH */ = {
isa = XCBuildConfiguration;
buildSettings = {
PRODUCT_NAME = lockut;
};
name = RASH;
};
22FA177216E8D6FC0098B23F /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@ -5547,6 +5657,16 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
22F846B918F437B900982BA7 /* Build configuration list for PBXNativeTarget "lockut" */ = {
isa = XCConfigurationList;
buildConfigurations = (
22F846BA18F437B900982BA7 /* Debug */,
22F846BB18F437B900982BA7 /* Release */,
22F846BC18F437B900982BA7 /* RASH */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
22FA177116E8D6FC0098B23F /* Build configuration list for PBXNativeTarget "amcssth" */ = {
isa = XCConfigurationList;
buildConfigurations = (

View file

@ -15,13 +15,8 @@
#include "fmtdytst.h"
#include "mps.h"
#include "mpstd.h"
#ifdef MPS_OS_W3
# include "mpsw3.h"
#endif
#include <stdlib.h>
#include <stdarg.h>
#include <math.h>
#include <string.h>
#include <stdio.h> /* printf */
#define exactRootsCOUNT 49

View file

@ -11,11 +11,15 @@
#ifndef mpswin_h
#define mpswin_h
#ifndef WIN32_LEAN_AND_MEAN
/* Speed up the build process by excluding parts of windows.h that we
* don't use. See <http://support.microsoft.com/kb/166474> */
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
#else
#include <windows.h>
#endif
#endif /* mpswin_h */

View file

@ -30,26 +30,36 @@ static Count nailboardLevels(Count nails)
}
/* nailboardNails -- return the total number of nails in the board */
static Count nailboardNails(Nailboard board)
{
return RangeSize(&board->range) >> board->alignShift;
}
/* nailboardLevelBits -- return the number of bits in the bit table
* for the given level.
*/
static Count nailboardLevelBits(Nailboard board, Index level)
static Count nailboardLevelBits(Count nails, Index level)
{
/* Use <= rather than < because of .check.levels. */
AVER(level <= board->levels);
return RangeSize(&board->range) >> (board->alignShift + level * LEVEL_SHIFT);
Shift shift = (Shift)(level * LEVEL_SHIFT);
return (nails + ((Count)1 << shift) - 1) >> shift;
}
Bool NailboardCheck(Nailboard board)
{
Index i;
Count nails;
CHECKS(Nailboard, board);
CHECKL(RangeCheck(&board->range));
CHECKL(0 < board->levels);
CHECKL(board->levels == nailboardLevels(nailboardLevelBits(board, 0)));
CHECKL(nailboardLevelBits(board, board->levels - 1) != 0);
CHECKL(nailboardLevelBits(board, board->levels) == 0); /* .check.levels */
nails = nailboardNails(board);
CHECKL(board->levels == nailboardLevels(nails));
CHECKL(nails == nailboardLevelBits(nails, 0));
CHECKL(nailboardLevelBits(nails, board->levels - 1) != 0);
CHECKL(nailboardLevelBits(nails, board->levels) == 1);
CHECKL(BoolCheck(board->newNails));
for (i = 0; i < board->levels; ++i) {
CHECKL(board->level[i] != NULL);
@ -80,8 +90,7 @@ static Size nailboardSize(Count nails, Count levels)
Size size;
size = nailboardStructSize(levels);
for (i = 0; i < levels; ++i) {
size += BTSize(nails);
nails >>= LEVEL_SHIFT;
size += BTSize(nailboardLevelBits(nails, i));
}
return size;
}
@ -130,11 +139,11 @@ Res NailboardCreate(Nailboard *boardReturn, Arena arena, Align alignment,
p = PointerAdd(p, nailboardStructSize(levels));
for (i = 0; i < levels; ++i) {
AVER(nails > 0);
Count levelBits = nailboardLevelBits(nails, i);
AVER(levelBits > 0);
board->level[i] = p;
BTResRange(board->level[i], 0, nails);
p = PointerAdd(p, BTSize(nails));
nails >>= LEVEL_SHIFT;
BTResRange(board->level[i], 0, levelBits);
p = PointerAdd(p, BTSize(levelBits));
}
board->sig = NailboardSig;
@ -154,7 +163,7 @@ void NailboardDestroy(Nailboard board, Arena arena)
AVERT(Nailboard, board);
AVERT(Arena, arena);
nails = nailboardLevelBits(board, 0);
nails = nailboardNails(board);
size = nailboardSize(nails, board->levels);
board->sig = SigInvalid;
@ -191,8 +200,10 @@ Bool (NailboardNewNails)(Nailboard board)
static Index nailboardIndex(Nailboard board, Index level, Addr addr)
{
return AddrOffset(RangeBase(&board->range), addr)
Index i = AddrOffset(RangeBase(&board->range), addr)
>> (board->alignShift + level * LEVEL_SHIFT);
AVER_CRITICAL(i < nailboardLevelBits(nailboardNails(board), level));
return i;
}
@ -414,7 +425,7 @@ Res NailboardDescribe(Nailboard board, mps_lib_FILE *stream)
return res;
for(i = 0; i < board->levels; ++i) {
Count levelNails = nailboardLevelBits(board, i);
Count levelNails = nailboardLevelBits(nailboardNails(board), i);
Count resetNails = BTCountResRange(board->level[i], 0, levelNails);
res = WriteF(stream, " Level $U ($U bits, $U set): ",
i, levelNails, levelNails - resetNails, NULL);

View file

@ -12,6 +12,8 @@
#include "bt.h"
#include "nailboard.h"
#include <stdio.h> /* printf */
static void test(mps_arena_t arena)
{

View file

@ -32,7 +32,7 @@ static Nailboard amcSegNailboard(Seg seg);
static Bool AMCCheck(AMC amc);
static Res AMCFix(Pool pool, ScanState ss, Seg seg, Ref *refIO);
static Res AMCHeaderFix(Pool pool, ScanState ss, Seg seg, Ref *refIO);
extern PoolClass AMCPoolClassGet(void);
extern PoolClass AMCZPoolClassGet(void);
extern BufferClass amcBufClassGet(void);
extern SegClass amcSegClassGet(void);
@ -2164,7 +2164,7 @@ static void amcWalkAll(Pool pool, FormattedObjectsStepMethod f,
Arena arena;
Ring ring, next, node;
AVER(IsSubclassPoly(pool->class, AMCPoolClassGet()));
AVER(IsSubclassPoly(pool->class, AMCZPoolClassGet()));
arena = PoolArena(pool);
ring = PoolSegRing(pool);
@ -2449,7 +2449,7 @@ static Bool AMCCheck(AMC amc)
{
CHECKS(AMC, amc);
CHECKD(Pool, &amc->poolStruct);
CHECKL(IsSubclassPoly(amc->poolStruct.class, EnsureAMCPoolClass()));
CHECKL(IsSubclassPoly(amc->poolStruct.class, AMCZPoolClassGet()));
CHECKL(RankSetCheck(amc->rankSet));
CHECKD_NOSIG(Ring, &amc->genRing);
CHECKL(BoolCheck(amc->gensBooted));

View file

@ -74,6 +74,11 @@ Bool AMSSegCheck(AMSSeg amsseg)
CHECKD_NOSIG(BT, amsseg->nongreyTable);
CHECKD_NOSIG(BT, amsseg->nonwhiteTable);
/* If tables are shared, they mustn't both be in use. */
CHECKL(!(amsseg->ams->shareAllocTable
&& amsseg->allocTableInUse
&& amsseg->colourTablesInUse));
return TRUE;
}
@ -167,6 +172,10 @@ static Res amsCreateTables(AMS ams, BT *allocReturn,
goto failWhite;
}
/* Invalidate the colour tables in checking varieties. */
AVER((BTResRange(nongreyTable, 0, length), TRUE));
AVER((BTSetRange(nonwhiteTable, 0, length), TRUE));
*allocReturn = allocTable;
*nongreyReturn = nongreyTable;
*nonwhiteReturn = nonwhiteTable;
@ -1023,7 +1032,8 @@ static void AMSBufferEmpty(Pool pool, Buffer buffer, Addr init, Addr limit)
AVER(limitIndex <= amsseg->firstFree);
if (limitIndex == amsseg->firstFree) /* is it at the end? */ {
amsseg->firstFree = initIndex;
} else { /* start using allocTable */
} else if (!ams->shareAllocTable || !amsseg->colourTablesInUse) {
/* start using allocTable */
amsseg->allocTableInUse = TRUE;
BTSetRange(amsseg->allocTable, 0, amsseg->firstFree);
if (amsseg->firstFree < amsseg->grains)
@ -1415,16 +1425,20 @@ static Res AMSFix(Pool pool, ScanState ss, Seg seg, Ref *refIO)
/* doing that here (this can be called from RootScan, during flip). */
clientRef = *refIO;
AVER_CRITICAL(SegBase(seg) <= clientRef);
AVER_CRITICAL(clientRef < SegLimit(seg)); /* see .ref-limit */
base = AddrSub((Addr)clientRef, format->headerSize);
/* can get an ambiguous reference too close to the base of the
* segment, so when we subtract the header we are not in the
* segment any longer. This isn't a real reference,
* so we can just skip it. */
if (base < SegBase(seg)) {
return ResOK;
AVER_CRITICAL(ss->rank == RankAMBIG);
return ResOK;
}
i = AMS_ADDR_INDEX(seg, base);
AVER_CRITICAL(i < amsseg->grains);
AVER_CRITICAL(!AMS_IS_INVALID_COLOUR(seg, i));
ss->wasMarked = TRUE;
@ -1584,12 +1598,13 @@ static void AMSReclaim(Pool pool, Trace trace, Seg seg)
/* preservedInPlaceCount is updated on fix */
trace->preservedInPlaceSize += (grains - amsseg->free) << ams->grainShift;
/* Ensure consistency of segment even if are just about to free it */
amsseg->colourTablesInUse = FALSE;
SegSetWhite(seg, TraceSetDel(SegWhite(seg), trace));
if (amsseg->free == grains && SegBuffer(seg) == NULL) {
/* No survivors */
SegFree(seg);
} else {
amsseg->colourTablesInUse = FALSE;
SegSetWhite(seg, TraceSetDel(SegWhite(seg), trace));
}
}

View file

@ -305,10 +305,14 @@ DEFINE_SEG_CLASS(AWLSegClass, class)
* it's possible to tweak them in a debugger.
*/
extern Count AWLSegSALimit;
Count AWLSegSALimit = AWL_SEG_SA_LIMIT;
extern Bool AWLHaveSegSALimit;
Bool AWLHaveSegSALimit = AWL_HAVE_SEG_SA_LIMIT;
extern Count AWLTotalSALimit;
Count AWLTotalSALimit = AWL_TOTAL_SA_LIMIT;
extern Bool AWLHaveTotalSALimit;
Bool AWLHaveTotalSALimit = AWL_HAVE_TOTAL_SA_LIMIT;
@ -558,6 +562,7 @@ static Res AWLInit(Pool pool, ArgList args)
AVERT(Format, format);
pool->format = format;
pool->alignment = format->alignment;
AVER(FUNCHECK(findDependent));
awl->findDependent = findDependent;
@ -570,7 +575,7 @@ static Res AWLInit(Pool pool, ArgList args)
if (res != ResOK)
goto failGenInit;
awl->alignShift = SizeLog2(pool->alignment);
awl->alignShift = SizeLog2(PoolAlignment(pool));
awl->size = (Size)0;
awl->succAccesses = 0;
@ -937,7 +942,7 @@ static Res awlScanSinglePass(Bool *anyScannedReturn,
i = awlIndexOfAddr(base, awl, p);
if (!BTGet(awlseg->alloc, i)) {
p = AddrAdd(p, pool->alignment);
p = AddrAdd(p, PoolAlignment(pool));
continue;
}
hp = AddrAdd(p, format->headerSize);
@ -954,7 +959,8 @@ static Res awlScanSinglePass(Bool *anyScannedReturn,
}
objectLimit = AddrSub(objectLimit, format->headerSize);
AVER(p < objectLimit);
p = AddrAlignUp(objectLimit, pool->alignment);
AVER(AddrIsAligned(objectLimit, PoolAlignment(pool)));
p = objectLimit;
}
AVER(p == limit);
@ -1051,7 +1057,7 @@ static Res AWLFix(Pool pool, ScanState ss, Seg seg, Ref *refIO)
switch(ss->rank) {
case RankAMBIG:
/* not a real pointer if not aligned or not allocated */
if (!AddrIsAligned(base, pool->alignment) || !BTGet(awlseg->alloc, i))
if (!AddrIsAligned(base, sizeof(void *)) || !BTGet(awlseg->alloc, i))
return ResOK;
/* falls through */
case RankEXACT:
@ -1125,7 +1131,7 @@ static void AWLReclaim(Pool pool, Trace trace, Seg seg)
}
q = format->skip(AddrAdd(p, format->headerSize));
q = AddrSub(q, format->headerSize);
q = AddrAlignUp(q, pool->alignment);
AVER(AddrIsAligned(q, PoolAlignment(pool)));
j = awlIndexOfAddr(base, awl, q);
AVER(j <= awlseg->grains);
if(BTGet(awlseg->mark, i)) {
@ -1243,13 +1249,13 @@ static void AWLWalk(Pool pool, Seg seg, FormattedObjectsStepMethod f,
i = awlIndexOfAddr(base, awl, object);
if (!BTGet(awlseg->alloc, i)) {
/* This grain is free */
object = AddrAdd(object, pool->alignment);
object = AddrAdd(object, PoolAlignment(pool));
continue;
}
object = AddrAdd(object, format->headerSize);
next = format->skip(object);
next = AddrSub(next, format->headerSize);
next = AddrAlignUp(next, pool->alignment);
AVER(AddrIsAligned(next, PoolAlignment(pool)));
if (BTGet(awlseg->mark, i) && BTGet(awlseg->scanned, i))
(*f)(object, pool->format, pool, p, s);
object = next;

View file

@ -136,7 +136,7 @@ static Res MFSInit(Pool pool, ArgList args)
mfs->sig = MFSSig;
AVERT(MFS, mfs);
EVENT5(PoolInitMFS, pool, arena, extendBy, extendSelf, unitSize);
EVENT5(PoolInitMFS, pool, arena, extendBy, BOOL(extendSelf), unitSize);
return ResOK;
}

View file

@ -1,41 +1,16 @@
/* poolmv.h: MANUAL VARIABLE POOL
*
* $Id$
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
* Portions copyright (C) 2002 Global Graphics Software.
*
* .purpose: This is the interface to the manual-variable pool class.
*
* .mv: Manual-variable pools manage variably-sized blocks of memory in a
* flexible manner. They have higher overheads than a fixed-size pool.
* .mv: Manual-variable pools manage variably-sized blocks of memory
* in a flexible manner. They have higher overheads than a fixed-size
* pool.
*
* .init: This class adds the following arguments to PoolCreate:
*
* Size extendBy
*
* extendBy is the default number of bytes reserved by the pool at a time.
* A large size will make allocation cheaper but have a higher resource
* overhead. A typical value might be 65536. See note 2.
*
* Size avgSize
*
* avgSize is an estimate of the average size of an allocation, and is used
* to choose the size of internal tables. An accurate estimate will
* improve the efficiency of the pool. A low estimate will make the pool
* less space efficient. A high estimate will make the pool less time
* efficient. A typical value might be 32. avgSize must not be less than
* extendBy.
*
* Size maxSize
*
* maxSize is an estimate of the maximum total size that the pool will
* reach. Setting this parameter does not actually contrain the pool, but
* an accurate estimate will improve the efficiency of the pool. maxSize
* must not be less than extendBy.
*
* Notes
* 2. The documentation could suggest a segment size according to the
* distribution of allocation size requests. richard 1994-11-08
* .design: See <design/poolmv/>
*/
#ifndef poolmv_h
@ -59,7 +34,7 @@ extern Bool MVCheck(MV mv);
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -81,7 +81,6 @@ typedef struct MVTStruct
Bool abqOverflow; /* ABQ dropped some candidates */
/* <design/poolmvt/#arch.ap.no-fit>.* */
Bool splinter; /* Saved splinter */
Seg splinterSeg; /* Saved splinter seg */
Addr splinterBase; /* Saved splinter base */
Addr splinterLimit; /* Saved splinter size */
@ -136,7 +135,7 @@ typedef struct MVTStruct
DEFINE_POOL_CLASS(MVTPoolClass, this)
{
INHERIT_CLASS(this, AbstractSegBufPoolClass);
INHERIT_CLASS(this, AbstractBufferPoolClass);
this->name = "MVT";
this->size = sizeof(MVTStruct);
this->offset = offsetof(MVTStruct, poolStruct);
@ -311,7 +310,6 @@ static Res MVTInit(Pool pool, ArgList args)
mvt->maxSize = maxSize;
mvt->fragLimit = fragLimit;
mvt->splinter = FALSE;
mvt->splinterSeg = NULL;
mvt->splinterBase = (Addr)0;
mvt->splinterLimit = (Addr)0;
@ -400,9 +398,7 @@ static Bool MVTCheck(MVT mvt)
if (mvt->splinter) {
CHECKL(AddrOffset(mvt->splinterBase, mvt->splinterLimit) >=
mvt->minSize);
CHECKD(Seg, mvt->splinterSeg);
CHECKL(mvt->splinterBase >= SegBase(mvt->splinterSeg));
CHECKL(mvt->splinterLimit <= SegLimit(mvt->splinterSeg));
CHECKL(mvt->splinterBase < mvt->splinterLimit);
}
CHECKL(mvt->size == mvt->allocated + mvt->available +
mvt->unavailable);
@ -937,7 +933,6 @@ static void MVTBufferEmpty(Pool pool, Buffer buffer,
}
mvt->splinter = TRUE;
mvt->splinterSeg = BufferSeg(buffer);
mvt->splinterBase = base;
mvt->splinterLimit = limit;
}
@ -984,8 +979,6 @@ static void MVTFree(Pool pool, Addr base, Size size)
AVER(mvt->size == mvt->allocated + mvt->available +
mvt->unavailable);
METER_ACC(mvt->exceptionReturns, SegSize(seg));
if (SegBuffer(seg) != NULL)
BufferDetach(SegBuffer(seg), MVT2Pool(mvt));
MVTSegFree(mvt, seg);
return;
}
@ -1017,7 +1010,6 @@ static Res MVTDescribe(Pool pool, mps_lib_FILE *stream)
" availLimit: $U \n", (WriteFU)mvt->availLimit,
" abqOverflow: $S \n", mvt->abqOverflow?"TRUE":"FALSE",
" splinter: $S \n", mvt->splinter?"TRUE":"FALSE",
" splinterSeg: $P \n", (WriteFP)mvt->splinterSeg,
" splinterBase: $A \n", (WriteFA)mvt->splinterBase,
" splinterLimit: $A \n", (WriteFU)mvt->splinterLimit,
" size: $U \n", (WriteFU)mvt->size,
@ -1036,68 +1028,37 @@ static Res MVTDescribe(Pool pool, mps_lib_FILE *stream)
res = ABQDescribe(MVTABQ(mvt), (ABQDescribeElement)RangeDescribe, stream);
if(res != ResOK) return res;
res = METER_WRITE(mvt->segAllocs, stream);
if (res != ResOK) return res;
res = METER_WRITE(mvt->segFrees, stream);
if (res != ResOK) return res;
res = METER_WRITE(mvt->bufferFills, stream);
if (res != ResOK) return res;
res = METER_WRITE(mvt->bufferEmpties, stream);
if (res != ResOK) return res;
res = METER_WRITE(mvt->poolFrees, stream);
if (res != ResOK) return res;
res = METER_WRITE(mvt->poolSize, stream);
if (res != ResOK) return res;
res = METER_WRITE(mvt->poolAllocated, stream);
if (res != ResOK) return res;
res = METER_WRITE(mvt->poolAvailable, stream);
if (res != ResOK) return res;
res = METER_WRITE(mvt->poolUnavailable, stream);
if (res != ResOK) return res;
res = METER_WRITE(mvt->poolUtilization, stream);
if (res != ResOK) return res;
res = METER_WRITE(mvt->finds, stream);
if (res != ResOK) return res;
res = METER_WRITE(mvt->overflows, stream);
if (res != ResOK) return res;
res = METER_WRITE(mvt->underflows, stream);
if (res != ResOK) return res;
res = METER_WRITE(mvt->refills, stream);
if (res != ResOK) return res;
res = METER_WRITE(mvt->refillPushes, stream);
if (res != ResOK) return res;
res = METER_WRITE(mvt->returns, stream);
if (res != ResOK) return res;
res = METER_WRITE(mvt->perfectFits, stream);
if (res != ResOK) return res;
res = METER_WRITE(mvt->firstFits, stream);
if (res != ResOK) return res;
res = METER_WRITE(mvt->secondFits, stream);
if (res != ResOK) return res;
res = METER_WRITE(mvt->failures, stream);
if (res != ResOK) return res;
res = METER_WRITE(mvt->emergencyContingencies, stream);
if (res != ResOK) return res;
res = METER_WRITE(mvt->fragLimitContingencies, stream);
if (res != ResOK) return res;
res = METER_WRITE(mvt->contingencySearches, stream);
if (res != ResOK) return res;
res = METER_WRITE(mvt->contingencyHardSearches, stream);
if (res != ResOK) return res;
res = METER_WRITE(mvt->splinters, stream);
if (res != ResOK) return res;
res = METER_WRITE(mvt->splintersUsed, stream);
if (res != ResOK) return res;
res = METER_WRITE(mvt->splintersDropped, stream);
if (res != ResOK) return res;
res = METER_WRITE(mvt->sawdust, stream);
if (res != ResOK) return res;
res = METER_WRITE(mvt->exceptions, stream);
if (res != ResOK) return res;
res = METER_WRITE(mvt->exceptionSplinters, stream);
if (res != ResOK) return res;
res = METER_WRITE(mvt->exceptionReturns, stream);
if (res != ResOK) return res;
METER_WRITE(mvt->segAllocs, stream);
METER_WRITE(mvt->segFrees, stream);
METER_WRITE(mvt->bufferFills, stream);
METER_WRITE(mvt->bufferEmpties, stream);
METER_WRITE(mvt->poolFrees, stream);
METER_WRITE(mvt->poolSize, stream);
METER_WRITE(mvt->poolAllocated, stream);
METER_WRITE(mvt->poolAvailable, stream);
METER_WRITE(mvt->poolUnavailable, stream);
METER_WRITE(mvt->poolUtilization, stream);
METER_WRITE(mvt->finds, stream);
METER_WRITE(mvt->overflows, stream);
METER_WRITE(mvt->underflows, stream);
METER_WRITE(mvt->refills, stream);
METER_WRITE(mvt->refillPushes, stream);
METER_WRITE(mvt->returns, stream);
METER_WRITE(mvt->perfectFits, stream);
METER_WRITE(mvt->firstFits, stream);
METER_WRITE(mvt->secondFits, stream);
METER_WRITE(mvt->failures, stream);
METER_WRITE(mvt->emergencyContingencies, stream);
METER_WRITE(mvt->fragLimitContingencies, stream);
METER_WRITE(mvt->contingencySearches, stream);
METER_WRITE(mvt->contingencyHardSearches, stream);
METER_WRITE(mvt->splinters, stream);
METER_WRITE(mvt->splintersUsed, stream);
METER_WRITE(mvt->splintersDropped, stream);
METER_WRITE(mvt->sawdust, stream);
METER_WRITE(mvt->exceptions, stream);
METER_WRITE(mvt->exceptionSplinters, stream);
METER_WRITE(mvt->exceptionReturns, stream);
res = WriteF(stream, "}\n", NULL);
return res;
@ -1175,7 +1136,7 @@ static Res MVTSegAlloc(Seg *segReturn, MVT mvt, Size size,
{
/* Can't use plain old SegClass here because we need to call
* SegBuffer() in MVTFree(). */
Res res = SegAlloc(segReturn, GCSegClassGet(),
Res res = SegAlloc(segReturn, SegClassGet(),
SegPrefDefault(), size, MVT2Pool(mvt), withReservoirPermit,
argsNone);
@ -1199,7 +1160,6 @@ static Res MVTSegAlloc(Seg *segReturn, MVT mvt, Size size,
*/
static void MVTSegFree(MVT mvt, Seg seg)
{
Buffer buffer;
Size size;
size = SegSize(seg);
@ -1209,16 +1169,6 @@ static void MVTSegFree(MVT mvt, Seg seg)
mvt->size -= size;
mvt->availLimit = mvt->size * mvt->fragLimit / 100;
AVER(mvt->size == mvt->allocated + mvt->available + mvt->unavailable);
/* If the client program allocates the exactly the entire buffer then
frees the allocated memory then we'll try to free the segment with
the buffer still attached. It's safe, but we must detach the buffer
first. See job003520 and job003672. */
buffer = SegBuffer(seg);
if (buffer != NULL) {
AVER(BufferAP(buffer)->init == SegLimit(seg));
BufferDetach(buffer, MVT2Pool(mvt));
}
SegFree(seg);
METER_ACC(mvt->segFrees, size);

View file

@ -539,7 +539,7 @@ static Res MVFFInit(Pool pool, ArgList args)
mvff->sig = MVFFSig;
AVERT(MVFF, mvff);
EVENT8(PoolInitMVFF, pool, arena, extendBy, avgSize, align,
slotHigh, arenaHigh, firstFit);
BOOL(slotHigh), BOOL(arenaHigh), BOOL(firstFit));
return ResOK;
failFailoverInit:

View file

@ -10,6 +10,8 @@
#include "testlib.h"
#include "mpslib.h"
#include <stdio.h> /* printf */
static void testit(ArenaClass class, ArgList args)
{

View file

@ -36,27 +36,34 @@ SRCID(prmci3li, "$Id$");
MRef Prmci3AddressHoldingReg(MutatorFaultContext mfc, unsigned int regnum)
{
MRef gregs;
AVER(mfc != NULL);
AVER(NONNEGATIVE(regnum));
AVER(regnum <= 7);
AVER(mfc->ucontext != NULL);
/* TODO: The current arrangement of the fix operation (taking a Ref *)
forces us to pun these registers (actually `int` on LII3GC). We can
suppress the warning by casting through `void *` and this might make
it safe, but does it really? RB 2012-09-10 */
AVER(sizeof(void *) == sizeof(*mfc->ucontext->uc_mcontext.gregs));
gregs = (void *)mfc->ucontext->uc_mcontext.gregs;
/* .source.i486 */
/* .assume.regref */
/* The register numbers (REG_EAX etc.) are defined in <ucontext.h>
but only if _GNU_SOURCE is defined: see .feature.li in
config.h. */
/* TODO: The current arrangement of the fix operation (taking a Ref *)
forces us to pun these registers (actually `int` on LII3GC). We can
suppress the warning my casting through `char *` and this might make
it safe, but does it really? RB 2012-09-10 */
switch (regnum) {
case 0: return (MRef)((char *)&mfc->ucontext->uc_mcontext.gregs[REG_EAX]);
case 1: return (MRef)((char *)&mfc->ucontext->uc_mcontext.gregs[REG_ECX]);
case 2: return (MRef)((char *)&mfc->ucontext->uc_mcontext.gregs[REG_EDX]);
case 3: return (MRef)((char *)&mfc->ucontext->uc_mcontext.gregs[REG_EBX]);
case 4: return (MRef)((char *)&mfc->ucontext->uc_mcontext.gregs[REG_ESP]);
case 5: return (MRef)((char *)&mfc->ucontext->uc_mcontext.gregs[REG_EBP]);
case 6: return (MRef)((char *)&mfc->ucontext->uc_mcontext.gregs[REG_ESI]);
case 7: return (MRef)((char *)&mfc->ucontext->uc_mcontext.gregs[REG_EDI]);
case 0: return &gregs[REG_EAX];
case 1: return &gregs[REG_ECX];
case 2: return &gregs[REG_EDX];
case 3: return &gregs[REG_EBX];
case 4: return &gregs[REG_ESP];
case 5: return &gregs[REG_EBP];
case 6: return &gregs[REG_ESI];
case 7: return &gregs[REG_EDI];
default:
NOTREACHED;
return NULL; /* Avoids compiler warning. */

View file

@ -34,8 +34,13 @@ SRCID(prmci3li, "$Id$");
MRef Prmci3AddressHoldingReg(MutatorFaultContext mfc, unsigned int regnum)
{
THREAD_STATE_S *threadState;
AVER(mfc != NULL);
AVER(NONNEGATIVE(regnum));
AVER(regnum <= 7);
AVER(mfc->threadState != NULL);
threadState = mfc->threadState;
/* .source.i486 */
/* .assume.regref */
@ -44,17 +49,17 @@ MRef Prmci3AddressHoldingReg(MutatorFaultContext mfc, unsigned int regnum)
config.h. */
/* TODO: The current arrangement of the fix operation (taking a Ref *)
forces us to pun these registers (actually `int` on LII3GC). We can
suppress the warning my casting through `char *` and this might make
suppress the warning by casting through `void *` and this might make
it safe, but does it really? RB 2012-09-10 */
switch (regnum) {
case 0: return (MRef)((char *)&mfc->threadState->__eax);
case 1: return (MRef)((char *)&mfc->threadState->__ecx);
case 2: return (MRef)((char *)&mfc->threadState->__edx);
case 3: return (MRef)((char *)&mfc->threadState->__ebx);
case 4: return (MRef)((char *)&mfc->threadState->__esp);
case 5: return (MRef)((char *)&mfc->threadState->__ebp);
case 6: return (MRef)((char *)&mfc->threadState->__esi);
case 7: return (MRef)((char *)&mfc->threadState->__edi);
case 0: return (void *)&threadState->__eax;
case 1: return (void *)&threadState->__ecx;
case 2: return (void *)&threadState->__edx;
case 3: return (void *)&threadState->__ebx;
case 4: return (void *)&threadState->__esp;
case 5: return (void *)&threadState->__ebp;
case 6: return (void *)&threadState->__esi;
case 7: return (void *)&threadState->__edi;
default:
NOTREACHED;
return NULL; /* Avoids compiler warning. */

View file

@ -33,12 +33,19 @@ SRCID(prmci6li, "$Id$");
MRef Prmci6AddressHoldingReg(MutatorFaultContext mfc, unsigned int regnum)
{
Word *gregs;
MRef gregs;
AVER(mfc != NULL);
AVER(NONNEGATIVE(regnum));
AVER(regnum <= 15);
AVER(mfc->ucontext != NULL);
gregs = (Word *)&mfc->ucontext->uc_mcontext.gregs;
/* TODO: The current arrangement of the fix operation (taking a Ref *)
forces us to pun these registers (actually `int` on LII6GC). We can
suppress the warning by casting through `void *` and this might make
it safe, but does it really? RB 2012-09-10 */
AVER(sizeof(void *) == sizeof(*mfc->ucontext->uc_mcontext.gregs));
gregs = (void *)mfc->ucontext->uc_mcontext.gregs;
/* .assume.regref */
/* The register numbers (REG_RAX etc.) are defined in <ucontext.h>

View file

@ -31,33 +31,38 @@ SRCID(prmci6li, "$Id$");
MRef Prmci6AddressHoldingReg(MutatorFaultContext mfc, unsigned int regnum)
{
THREAD_STATE_S *threadState;
AVER(mfc != NULL);
AVER(NONNEGATIVE(regnum));
AVER(regnum <= 15);
AVER(mfc->threadState != NULL);
threadState = mfc->threadState;
/* .assume.regref */
/* The register numbers (REG_RAX etc.) are defined in <ucontext.h>
but only if _XOPEN_SOURCE is defined: see .feature.xc in
config.h. */
/* MRef (a Word *) is not compatible with pointers to the register
types (actually a __uint64_t). To avoid aliasing optimization
problems, The registers are cast through (char *) */
types (actually a __uint64_t). To avoid aliasing optimization
problems, the registers are cast through (void *). */
switch (regnum) {
case 0: return (MRef)((char *)&mfc->threadState->__rax);
case 1: return (MRef)((char *)&mfc->threadState->__rcx);
case 2: return (MRef)((char *)&mfc->threadState->__rdx);
case 3: return (MRef)((char *)&mfc->threadState->__rbx);
case 4: return (MRef)((char *)&mfc->threadState->__rsp);
case 5: return (MRef)((char *)&mfc->threadState->__rbp);
case 6: return (MRef)((char *)&mfc->threadState->__rsi);
case 7: return (MRef)((char *)&mfc->threadState->__rdi);
case 8: return (MRef)((char *)&mfc->threadState->__r8);
case 9: return (MRef)((char *)&mfc->threadState->__r9);
case 10: return (MRef)((char *)&mfc->threadState->__r10);
case 11: return (MRef)((char *)&mfc->threadState->__r11);
case 12: return (MRef)((char *)&mfc->threadState->__r12);
case 13: return (MRef)((char *)&mfc->threadState->__r13);
case 14: return (MRef)((char *)&mfc->threadState->__r14);
case 15: return (MRef)((char *)&mfc->threadState->__r15);
case 0: return (void *)&threadState->__rax;
case 1: return (void *)&threadState->__rcx;
case 2: return (void *)&threadState->__rdx;
case 3: return (void *)&threadState->__rbx;
case 4: return (void *)&threadState->__rsp;
case 5: return (void *)&threadState->__rbp;
case 6: return (void *)&threadState->__rsi;
case 7: return (void *)&threadState->__rdi;
case 8: return (void *)&threadState->__r8;
case 9: return (void *)&threadState->__r9;
case 10: return (void *)&threadState->__r10;
case 11: return (void *)&threadState->__r11;
case 12: return (void *)&threadState->__r12;
case 13: return (void *)&threadState->__r13;
case 14: return (void *)&threadState->__r14;
case 15: return (void *)&threadState->__r15;
default:
NOTREACHED;
return NULL; /* Avoids compiler warning. */

View file

@ -243,7 +243,7 @@ static void protCatchOne(void)
different size" warnings in GCC, for the XCI3GC build. */
mfcStruct.address = (Addr)(Word)request.code[1];
AVER(sizeof(*mfcStruct.threadState) == sizeof(THREAD_STATE_S));
mfcStruct.threadState = (THREAD_STATE_S *)request.old_state;
mfcStruct.threadState = (void *)request.old_state;
if (ArenaAccess(mfcStruct.address,
AccessREAD | AccessWRITE,
@ -282,6 +282,7 @@ static void protCatchOne(void)
* handler won't cause a deadlock.
*/
ATTRIBUTE_NORETURN
static void *protCatchThread(void *p) {
UNUSED(p);
for (;;)

View file

@ -29,10 +29,9 @@
#include "mpscamc.h"
#include "mpscmv.h"
#include "mpstd.h"
#ifdef MPS_OS_W3
#include "mpsw3.h"
#endif
#include <stdlib.h>
#include <stdio.h> /* printf */
#include <stdlib.h> /* qsort */
#define testArenaSIZE ((size_t)1000*1024)
@ -51,7 +50,7 @@ static mps_addr_t isMoved(mps_addr_t object);
static void copy(mps_addr_t object, mps_addr_t to);
static void pad(mps_addr_t base, size_t size);
struct mps_fmt_A_s fmt_A_s =
static struct mps_fmt_A_s fmt_A_s =
{
(mps_align_t)4,
scan, skip, copy,
@ -318,14 +317,14 @@ static void validate(void)
for(i = 0; i < listl; ++i) {
cdie(((QSCell)reg[1])->tag == QSInt, "validate int");
if((mps_word_t)((QSCell)reg[1])->value != list[i]) {
(void)fprintf(stdout, "mps_res_t: Element %"PRIuLONGEST" of the "
"two lists do not match.\n", (ulongest_t)i);
printf("mps_res_t: Element %"PRIuLONGEST" of the "
"two lists do not match.\n", (ulongest_t)i);
return;
}
reg[1] = (mps_addr_t)((QSCell)reg[1])->tail;
}
cdie(reg[1] == (mps_word_t)0, "validate end");
(void)fprintf(stdout, "Note: Lists compare equal.\n");
printf("Note: Lists compare equal.\n");
}

View file

@ -1,7 +1,7 @@
/* ring.c: RING IMPLEMENTATION
*
* $Id$
* Copyright (c) 2001,2003 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
* .intro: This is a portable implementation of Rings.
*
@ -52,6 +52,16 @@ Bool RingIsSingle(Ring ring)
return (ring->next == ring);
}
Size RingLength(Ring ring)
{
Size size = 0;
Ring node, next;
AVERT(Ring, ring);
RING_FOR(node, ring, next)
++ size;
return size;
}
/* RingInit -- initialize a ring node
*/
@ -131,7 +141,7 @@ Ring (RingPrev)(Ring ring)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2003 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -1,7 +1,7 @@
/* ring.h: RING INTERFACE
*
* $Id$
* Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
* Portions copyright (C) 2001 Global Graphics Software.
*/
@ -30,6 +30,7 @@ typedef struct RingStruct { /* double-ended queue structure */
extern Bool RingCheck(Ring ring);
extern Bool RingCheckSingle(Ring ring);
extern Bool RingIsSingle(Ring ring);
extern Size RingLength(Ring ring);
/* .ring.init: */
extern void (RingInit)(Ring ring);
@ -115,7 +116,7 @@ extern Ring (RingPrev)(Ring ring);
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2013 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -48,18 +48,20 @@ static Bool SACCheck(SAC sac)
CHECKL(esac->_middle > 0);
/* check classes above middle */
prevSize = esac->_middle;
for (j = sac->middleIndex + 1, i = 0;
j <= sac->classesCount; ++j, i += 2) {
for (j = sac->middleIndex + 1, i = 0; j < sac->classesCount; ++j, i += 2) {
CHECKL(prevSize < esac->_freelists[i]._size);
b = sacFreeListBlockCheck(&(esac->_freelists[i]));
if (!b) return b;
prevSize = esac->_freelists[i]._size;
}
/* check overlarge class */
CHECKL(esac->_freelists[i-2]._size == SizeMAX);
CHECKL(esac->_freelists[i-2]._count == 0);
CHECKL(esac->_freelists[i-2]._count_max == 0);
CHECKL(esac->_freelists[i-2]._blocks == NULL);
CHECKL(prevSize < esac->_freelists[i]._size);
b = sacFreeListBlockCheck(&(esac->_freelists[i]));
if (!b) return b;
CHECKL(esac->_freelists[i]._size == SizeMAX);
CHECKL(esac->_freelists[i]._count == 0);
CHECKL(esac->_freelists[i]._count_max == 0);
CHECKL(esac->_freelists[i]._blocks == NULL);
/* check classes below middle */
prevSize = esac->_middle;
for (j = sac->middleIndex, i = 1; j > 0; --j, i += 2) {
@ -69,6 +71,7 @@ static Bool SACCheck(SAC sac)
prevSize = esac->_freelists[i]._size;
}
/* check smallest class */
CHECKL(prevSize > esac->_freelists[i]._size);
CHECKL(esac->_freelists[i]._size == 0);
b = sacFreeListBlockCheck(&(esac->_freelists[i]));
return b;

View file

@ -593,7 +593,7 @@ Res SegMerge(Seg *mergedSegReturn, Seg segLo, Seg segHi,
if (ResOK != res)
goto failMerge;
EVENT3(SegMerge, segLo, segHi, withReservoirPermit);
EVENT3(SegMerge, segLo, segHi, BOOL(withReservoirPermit));
/* Deallocate segHi object */
ControlFree(arena, segHi, class->size);
AVERT(Seg, segLo);
@ -1200,7 +1200,7 @@ static void gcSegSetGreyInternal(Seg seg, TraceSet oldGrey, TraceSet grey)
/* Internal method. Parameters are checked by caller */
gcseg = SegGCSeg(seg);
arena = PoolArena(SegPool(seg));
seg->grey = grey;
seg->grey = BS_BITFIELD(Trace, grey);
/* If the segment is now grey and wasn't before, add it to the */
/* appropriate grey list so that TraceFindGrey can locate it */
@ -1313,11 +1313,11 @@ static void gcSegSetWhite(Seg seg, TraceSet white)
AVERT_CRITICAL(Tract, tract);
AVER_CRITICAL(TRACT_SEG(&trseg, tract) && (trseg == seg));
TractSetWhite(tract, white);
TractSetWhite(tract, BS_BITFIELD(Trace, white));
}
AVER(addr == limit);
seg->white = white;
seg->white = BS_BITFIELD(Trace, white);
}
@ -1350,7 +1350,7 @@ static void gcSegSetRankSet(Seg seg, RankSet rankSet)
arena = PoolArena(SegPool(seg));
oldRankSet = seg->rankSet;
seg->rankSet = rankSet;
seg->rankSet = BS_BITFIELD(Rank, rankSet);
if (oldRankSet == RankSetEMPTY) {
if (rankSet != RankSetEMPTY) {
@ -1427,7 +1427,7 @@ static void gcSegSetRankSummary(Seg seg, RankSet rankSet, RefSet summary)
wasShielded = (seg->rankSet != RankSetEMPTY && gcseg->summary != RefSetUNIV);
willbeShielded = (rankSet != RankSetEMPTY && summary != RefSetUNIV);
seg->rankSet = rankSet;
seg->rankSet = BS_BITFIELD(Rank, rankSet);
gcseg->summary = summary;
if (willbeShielded && !wasShielded) {

View file

@ -21,14 +21,9 @@
#include "mpscams.h"
#include "mpsavm.h"
#include "mpstd.h"
#ifdef MPS_OS_W3
#include "mpsw3.h"
#endif
#include "mps.h"
#include <stdlib.h>
#include <stdarg.h>
#include <math.h>
#include <string.h>
#include <stdio.h> /* fflush, printf, puts, stdout */
/* Forward declarations */
@ -791,7 +786,7 @@ static void *test(void *arg, size_t s)
&ambigRoots[0], ambigRootsCOUNT),
"root_create_table(ambig)");
(void)fputs(indent, stdout);
puts(indent);
/* create an ap, and leave it busy */
die(mps_reserve(&busy_init, busy_ap, 64), "mps_reserve busy");

View file

@ -14,12 +14,9 @@
#include "mpscamc.h"
#include "mpsavm.h"
#include "mpstd.h"
#ifdef MPS_OS_W3
#include "mpsw3.h"
#endif
#include "mps.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h> /* fflush, printf, putchar, stdout */
#define testArenaSIZE ((size_t)((size_t)64 << 20))
#define avLEN 3
@ -74,19 +71,19 @@ static mps_addr_t ambigRoots[ambigRootsCOUNT];
/* Things we want to measure. Times are all in microseconds. */
double alloc_time; /* Time spent allocating */
double max_alloc_time; /* Max time taken to allocate one object */
double step_time; /* Time spent in mps_arena_step returning 1 */
double max_step_time; /* Max time of mps_arena_step returning 1 */
double no_step_time; /* Time spent in mps_arena_step returning 0 */
double max_no_step_time; /* Max time of mps_arena_step returning 0 */
static double alloc_time; /* Time spent allocating */
static double max_alloc_time; /* Max time taken to allocate one object */
static double step_time; /* Time spent in mps_arena_step returning 1 */
static double max_step_time; /* Max time of mps_arena_step returning 1 */
static double no_step_time; /* Time spent in mps_arena_step returning 0 */
static double max_no_step_time; /* Max time of mps_arena_step returning 0 */
double total_clock_time; /* Time spent reading the clock */
long clock_reads; /* Number of times clock is read */
long steps; /* # of mps_arena_step calls returning 1 */
long no_steps; /* # of mps_arena_step calls returning 0 */
size_t alloc_bytes; /* # of bytes allocated */
long commit_failures; /* # of times mps_commit fails */
static double total_clock_time; /* Time spent reading the clock */
static long clock_reads; /* Number of times clock is read */
static long steps; /* # of mps_arena_step calls returning 1 */
static long no_steps; /* # of mps_arena_step calls returning 0 */
static size_t alloc_bytes; /* # of bytes allocated */
static long commit_failures; /* # of times mps_commit fails */
/* Operating-system dependent timing. Defines two functions, void
@ -98,6 +95,8 @@ long commit_failures; /* # of times mps_commit fails */
#ifdef MPS_OS_W3
#include "mpswin.h"
static HANDLE currentProcess;
static void prepare_clock(void)
@ -152,7 +151,7 @@ static double my_clock(void)
* on thrush.ravenbrook.com on 2002-06-28, clock_time goes from 5.43
* us near process start to 7.45 us later). */
double clock_time; /* current estimate of time to read the clock */
static double clock_time; /* current estimate of time to read the clock */
/* take at least this many microseconds to set the clock */
#define CLOCK_TIME_SET 10000

View file

@ -12,7 +12,8 @@
#include "testlib.h"
#include "mpslib.h"
#include <stdlib.h>
#include <stdio.h> /* fflush, fgets, printf, stdin, stdout */
#include <stdlib.h> /* exit, EXIT_SUCCESS, strtoul */
SRCID(teletest, "$Id$");
@ -34,8 +35,8 @@ static void callControl(mps_word_t reset, mps_word_t flip)
old = mps_telemetry_control(reset, flip);
new = mps_telemetry_control((mps_word_t)0, (mps_word_t)0);
(void)printf(WORD_FORMAT " -> " WORD_FORMAT "\n",
(ulongest_t)old, (ulongest_t)new);
printf(WORD_FORMAT " -> " WORD_FORMAT "\n",
(ulongest_t)old, (ulongest_t)new);
}

View file

@ -11,13 +11,11 @@
#include "clock.h" /* for EVENT_CLOCK */
#include "mps.h"
#include "misc.h" /* for NOOP */
#include <math.h>
#include <stdlib.h>
#include <limits.h>
#ifdef MPS_OS_IA
struct itimerspec; /* stop complaints from time.h */
#endif
#include <time.h>
#include <math.h> /* fmod */
#include <stdio.h> /* fflush, printf, stderr, sscanf, vfprintf */
#include <stdlib.h> /* abort, exit, getenv */
#include <time.h> /* time */
/* fail -- like assert, but (notionally) returns a value, so usable in an expression */

View file

@ -12,14 +12,7 @@
#include "mps.h"
#include "misc.h" /* for STR */
/* Include system header hackery. */
#include "mpstd.h"
#ifdef MPS_OS_W3
#include "mpswin.h"
#endif
#include <stdio.h>
/* Suppress Visual C warnings at warning level 4, */
@ -35,13 +28,10 @@
/* Suppress Pelles C warnings at warning level 2 */
/* Some of these are also done in config.h. */
/* This is also done in config.h. */
#ifdef MPS_BUILD_PC
/* "Structured Exception Handling is not portable." (mps_tramp). */
#pragma warn(disable: 2008)
/* "Unreachable code" (AVER, if condition is constantly true). */
#pragma warn(disable: 2154)
@ -65,6 +55,19 @@
#endif
/* alloca -- memory allocator
*
* Windows calls this function _alloca() instead of alloca().
* <http://msdn.microsoft.com/en-us/library/wb1s57t5.aspx>
*/
#if defined(MPS_OS_W3)
#define alloca _alloca
#endif
/* ulongest_t -- longest unsigned integer type
*
* Define a longest unsigned integer type for testing, scanning, and

123
mps/code/testthr.h Normal file
View file

@ -0,0 +1,123 @@
/* testthr.h: MULTI-THREADED TEST INTERFACE
*
* $Id: //info.ravenbrook.com/project/mps/master/code/testlib.h#30 $
* Copyright (c) 2014 Ravenbrook Limited. See end of file for license.
*
* .purpose: Simple interface to threads that makes it possible to
* write test cases that are portable between Windows (using the
* implementation in testthrw3.c) and Unix (using the implementation
* in testthrix.c).
*/
#ifndef testthr_h
#define testthr_h
#include "mpstd.h"
/* testthr_routine_t -- type of thread routines
*
* Use the pthread type here and convert back and forth in the Windows
* implementation.
*/
typedef void *(*testthr_routine_t)(void *);
/* testthr_t -- type of thread identifiers
*
* It is necessary to define it here (even though it requires some
* #ifdefs) so that clients can allocate storage for them.
*/
#if defined(MPS_OS_W3)
#include "mpswin.h"
/* On Windows, a thread is identified by a HANDLE.
* <http://msdn.microsoft.com/en-us/library/windows/desktop/aa383751.aspx>
* But use a structure so that the thread has somewhere to store its
* result for use by testthr_join.
*/
typedef struct testthr_t {
HANDLE handle;
testthr_routine_t start;
void *arg; /* argument to pass to start */
void *result; /* result returned from start */
} testthr_t;
#elif defined(MPS_OS_FR) || defined(MPS_OS_LI) || defined(MPS_OS_XC)
#include <pthread.h>
/* In pthreads, a thread is identified by a pthread_t, which is
* allowed "to be defined as a structure" [IEEE Std 1003.1, sys/types.h]
* <http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_types.h.html>
*/
typedef pthread_t testthr_t;
#else
#error "Unknown platform: can't determine a type for testthr_t."
#endif
/* testthr_create -- create a thread
*
* Store the identifier of the newly created thread in *thread_o, and
* call start, passing arg as the single parameter.
*/
void testthr_create(testthr_t *thread_o, testthr_routine_t start, void *arg);
/* testthr_join -- wait for a thread to complete
*
* Suspend execution of the calling thread until the target thread
* terminates (if necessary), and if result_o is non-NULL, update
* *result_o with the return value of the thread's start.
*/
void testthr_join(testthr_t *thread, void **result_o);
#endif /* testthr_h */
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Redistributions in any form must be accompanied by information on how
* to obtain complete source code for this software and any accompanying
* software that uses this software. The source code must either be
* included in the distribution or be available for no more than the cost
* of distribution plus a nominal fee, and must be freely redistributable
* under reasonable conditions. For an executable file, complete source
* code means the source code for all modules it contains. It does not
* include source code for modules or files that typically accompany the
* major components of the operating system on which the executable file
* runs.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE, OR NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

View file

@ -1,45 +1,32 @@
/* mpsw3.h: RAVENBROOK MEMORY POOL SYSTEM C INTERFACE, WINDOWS PART
/* testthrix.c: MULTI-THREADED TEST IMPLEMENTATION (POSIX THREADS)
*
* $Id$
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
*
* .readership: customers, MPS developers.
* .sources: <design/interface-c/>.
* $Id: //info.ravenbrook.com/project/mps/master/code/testlib.h#30 $
* Copyright (c) 2014 Ravenbrook Limited. See end of file for license.
*/
#ifndef mpsw3_h
#define mpsw3_h
#include "testlib.h"
#include "testthr.h"
#include "mps.h" /* needed for mps_tramp_t */
#include "mpswin.h" /* needed for SEH filter */
#include <string.h> /* strerror */
void testthr_create(testthr_t *thread_o, testthr_routine_t start, void *arg)
{
int res = pthread_create(thread_o, NULL, start, arg);
if (res != 0)
error("pthread_create failed with result %d (%s)", res, strerror(res));
}
extern LONG mps_SEH_filter(LPEXCEPTION_POINTERS, void **, size_t *);
extern void mps_SEH_handler(void *, size_t);
#define mps_tramp(r_o, f, p, s) \
MPS_BEGIN \
void **_r_o = (r_o); \
mps_tramp_t _f = (f); \
void *_p = (p); \
size_t _s = (s); \
void *_hp = NULL; size_t _hs = 0; \
__try { \
*_r_o = (*_f)(_p, _s); \
} __except(mps_SEH_filter(GetExceptionInformation(), \
&_hp, &_hs)) { \
mps_SEH_handler(_hp, _hs); \
} \
MPS_END
#endif /* mpsw3_h */
void testthr_join(testthr_t *thread, void **result_o)
{
int res = pthread_join(*thread, result_o);
if (res != 0)
error("pthread_join failed with result %d (%s)", res, strerror(res));
}
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

80
mps/code/testthrw3.c Normal file
View file

@ -0,0 +1,80 @@
/* testthrw3.c: MULTI-THREADED TEST IMPLEMENTATION (WINDOWS)
*
* $Id: //info.ravenbrook.com/project/mps/master/code/testlib.h#30 $
* Copyright (c) 2014 Ravenbrook Limited. See end of file for license.
*/
#include "testlib.h"
#include "testthr.h"
static DWORD WINAPI testthr_start(LPVOID arg)
{
testthr_t *thread = arg;
thread->result = (*thread->start)(thread->arg);
return 0;
}
void testthr_create(testthr_t *thread_o, testthr_routine_t start, void *arg)
{
HANDLE res;
thread_o->start = start;
thread_o->arg = arg;
res = CreateThread(NULL, 0, testthr_start, thread_o, 0, NULL);
if (res == NULL)
error("CreateThread failed with error %lu",
(unsigned long)GetLastError());
else
thread_o->handle = res;
}
void testthr_join(testthr_t *thread, void **result_o)
{
DWORD res = WaitForSingleObject(thread->handle, INFINITE);
if (res != WAIT_OBJECT_0)
error("WaitForSingleObject failed with result %lu (error %lu)",
(unsigned long)res, (unsigned long)GetLastError());
if (result_o)
*result_o = thread->result;
}
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Redistributions in any form must be accompanied by information on how
* to obtain complete source code for this software and any accompanying
* software that uses this software. The source code must either be
* included in the distribution or be available for no more than the cost
* of distribution plus a nominal fee, and must be freely redistributable
* under reasonable conditions. For an executable file, complete source
* code means the source code for all modules it contains. It does not
* include source code for modules or files that typically accompany the
* major components of the operating system on which the executable file
* runs.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE, OR NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

View file

@ -797,10 +797,11 @@ void TraceDestroy(Trace trace)
(TraceStatReclaim, trace,
trace->reclaimCount, trace->reclaimSize));
EVENT1(TraceDestroy, trace);
trace->sig = SigInvalid;
trace->arena->busyTraces = TraceSetDel(trace->arena->busyTraces, trace);
trace->arena->flippedTraces = TraceSetDel(trace->arena->flippedTraces, trace);
EVENT1(TraceDestroy, trace);
}
@ -1569,7 +1570,7 @@ static void TraceStartPoolGen(Chain chain, GenDesc desc, Bool top, Index i)
Ring n, nn;
RING_FOR(n, &desc->locusRing, nn) {
PoolGen gen = RING_ELT(PoolGen, genRing, n);
EVENT11(TraceStartPoolGen, chain, top, i, desc,
EVENT11(TraceStartPoolGen, chain, BOOL(top), i, desc,
desc->capacity, desc->mortality, desc->zones,
gen->pool, gen->nr, gen->totalSize,
gen->newSizeAtCreate);

View file

@ -47,6 +47,7 @@ SRCID(version, "$Id$");
* (assuming we've made any substantial changes to the library this year).
*/
extern char MPSCopyrightNotice[];
char MPSCopyrightNotice[] =
"Portions copyright (c) 2010-2014 Ravenbrook Limited and Global Graphics Software.";
@ -59,6 +60,7 @@ char MPSCopyrightNotice[] =
* see also guide.mps.version.
*/
extern char MPSVersionString[];
char MPSVersionString[] =
"@(#)Ravenbrook MPS, "
"product." MPS_PROD_STRING ", " MPS_RELEASE ", platform." MPS_PF_STRING

View file

@ -1,7 +1,7 @@
/* vman.c: ANSI VM: MALLOC-BASED PSEUDO MEMORY MAPPING
*
* $Id$
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*/
#include "mpm.h"
@ -117,13 +117,13 @@ void VMDestroy(VM vm)
AVER(vm->mapped == (Size)0);
AVER(vm->reserved == AddrOffset(vm->base, vm->limit));
EVENT1(VMDestroy, vm);
memset((void *)vm->base, VMJunkBYTE, AddrOffset(vm->base, vm->limit));
free(vm->block);
vm->sig = SigInvalid;
free(vm);
EVENT1(VMDestroy, vm);
free(vm);
}
@ -215,7 +215,7 @@ void VMUnmap(VM vm, Addr base, Addr limit)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -1,7 +1,7 @@
/* vmix.c: VIRTUAL MEMORY MAPPING FOR UNIX (ISH)
*
* $Id$
* Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
* .purpose: This is the implementation of the virtual memory mapping
* interface (vm.h) for Unix-like operating systems. It was created
@ -186,6 +186,8 @@ void VMDestroy(VM vm)
AVERT(VM, vm);
AVER(vm->mapped == (Size)0);
EVENT1(VMDestroy, vm);
/* This appears to be pretty pointless, since the descriptor */
/* page is about to vanish completely. However, munmap might fail */
/* for some reason, and this would ensure that it was still */
@ -197,8 +199,6 @@ void VMDestroy(VM vm)
r = munmap((void *)vm,
(size_t)SizeAlignUp(sizeof(VMStruct), vm->align));
AVER(r == 0);
EVENT1(VMDestroy, vm);
}
@ -304,7 +304,7 @@ void VMUnmap(VM vm, Addr base, Addr limit)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2013 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -1,7 +1,7 @@
/* vmw3.c: VIRTUAL MEMORY MAPPING FOR WIN32
*
* $Id$
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
* .design: See <design/vm/>.
*
@ -191,6 +191,8 @@ void VMDestroy(VM vm)
AVERT(VM, vm);
AVER(vm->mapped == 0);
EVENT1(VMDestroy, vm);
/* This appears to be pretty pointless, since the vm descriptor page
* is about to vanish completely. However, the VirtualFree might
* fail and it would be nice to have a dead sig there. */
@ -201,7 +203,6 @@ void VMDestroy(VM vm)
b = VirtualFree((LPVOID)vm, (SIZE_T)0, MEM_RELEASE);
AVER(b != 0);
EVENT1(VMDestroy, vm);
}
@ -303,7 +304,7 @@ void VMUnmap(VM vm, Addr base, Addr limit)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -273,6 +273,20 @@ static Res rootWalk(Root root, void *p)
}
/* rootWalkGrey -- make the root grey for the trace passed as p */
static Res rootWalkGrey(Root root, void *p)
{
Trace trace = p;
AVERT(Root, root);
AVERT(Trace, trace);
RootGrey(root, trace);
return ResOK;
}
/* ArenaRootsWalk -- walks all the root in the arena */
static Res ArenaRootsWalk(Globals arenaGlobals, mps_roots_stepper_t f,
@ -315,7 +329,7 @@ static Res ArenaRootsWalk(Globals arenaGlobals, mps_roots_stepper_t f,
}
/* Make the roots grey so that they are scanned */
res = RootsIterate(arenaGlobals, (RootIterateFn)RootGrey, (void *)trace);
res = RootsIterate(arenaGlobals, rootWalkGrey, trace);
/* Make this trace look like any other trace. */
arena->flippedTraces = TraceSetAdd(arena->flippedTraces, trace);
@ -330,6 +344,16 @@ static Res ArenaRootsWalk(Globals arenaGlobals, mps_roots_stepper_t f,
break;
}
/* Turn segments black again. */
if (SegFirst(&seg, arena)) {
do {
if (PoolHasAttr(SegPool(seg), AttrGC)) {
SegSetGrey(seg, TraceSetDel(SegGrey(seg), trace));
SegSetWhite(seg, TraceSetDel(SegWhite(seg), trace));
}
} while (SegNext(&seg, arena, seg));
}
rootsStepClosureFinish(rsc);
/* Make this trace look like any other finished trace. */
trace->state = TraceFINISHED;

View file

@ -13,15 +13,12 @@
#include "mpscamc.h"
#include "mpscams.h"
#include "mpscawl.h"
#include "mpsclo.h"
#include "mpsavm.h"
#include "mpstd.h"
#ifdef MPS_OS_W3
#include "mpsw3.h"
#endif
#include "mps.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h> /* printf */
#define testArenaSIZE ((size_t)((size_t)64 << 20))
#define avLEN 3
@ -216,8 +213,10 @@ int main(int argc, char *argv[])
die(mps_thread_reg(&thread, arena), "thread_reg");
test(arena, mps_class_amc());
test(arena, mps_class_awl());
test(arena, mps_class_amcz());
/* TODO: test(arena, mps_class_ams()); -- see job003738 */
test(arena, mps_class_awl());
test(arena, mps_class_lo());
mps_thread_dereg(thread);
mps_arena_destroy(arena);

View file

@ -62,11 +62,8 @@
#include "fmtdy.h"
#include "fmtdytst.h"
#include "mpstd.h"
#ifdef MPS_OS_W3
#include "mpsw3.h"
#endif
#include <stdlib.h>
#include <time.h> /* clock */
#include <stdio.h> /* fflush, printf, putchar, puts, stdout */
/* testChain -- generation parameters for the test */

View file

@ -107,10 +107,8 @@
#include "fmtdy.h"
#include "fmtdytst.h"
#include "mpstd.h"
#ifdef MPS_OS_W3
#include "mpsw3.h"
#endif
#include <stdlib.h>
#include <stdio.h> /* printf */
#define testArenaSIZE ((size_t)16<<20)

View file

@ -187,8 +187,8 @@ Performance might be improved by special-casing the small levels.
_`.future.limit`: In C and C++, a pointer to "one past the last
element of an array object" (the limit of the object in our
terminology) is a valid pointer and can be used in pointer arithmetic.
See §6.5.6.89 of [C1999]. So in theory a programmer could have such
as pointer as the only reference keeping an object alive, and still
See §6.5.6.89 of [C1999]_. So in theory a programmer could have such
a pointer as the only reference keeping an object alive, and still
expect to be able to subtract from it to get back to the object. The
current nailboard implementation does not support this use case.

View file

@ -1,5 +1,6 @@
# The files in this directory are generated by the "mps" extension to Sphinx,
# except the index and the "old designs" index.
*.rst
*.svg
!index.rst
!old.rst

View file

@ -18,11 +18,14 @@ from sphinx.util.console import bold
TYPES = '''
AccessSet Accumulation Addr Align AP Arg Arena Attr Bool BT Buffer
Byte Clock Compare Count Epoch Format Fun Index LD Lock Message
Pointer Pool PThreadext Rank RankSet Ref Res Reservoir Ring Root
RootVar ScanState Seg Serial Shift Sig Size Space SplayNode
SplayTree Thread Trace TraceId TraceSet ULongest VM Word
AccessSet Accumulation Addr Align AllocFrame AllocPattern AP Arg
Arena Attr Bool BootBlock BT Buffer BufferMode Byte Chain Chunk
Clock Compare Count Epoch FindDelete Format FrameState Fun Globals
Index Land LD Lock Message MessageType MutatorFaultContext Page
Pointer Pool PThreadext Range Rank RankSet Ref Res Reservoir Ring
Root RootMode RootVar ScanState Seg SegBuf SegPref SegPrefKind
Serial Shift Sig Size Space SplayNode SplayTree StackContext
Thread Trace TraceId TraceSet ULongest VM Word ZoneSet
'''

View file

@ -14,7 +14,7 @@ Memory Management Glossary: K
keyword argument
A argument to a function call that's identified by an
An argument to a function call that's identified by an
associated keyword rather than by its position in the argument
list.
@ -35,5 +35,3 @@ Memory Management Glossary: K
The standard abbreviation is "kB", but "KB" is often used by
people unfamiliar with the metric system.

View file

@ -282,11 +282,10 @@ the format of objects allocated in it:
that it does not look like an aligned pointer.
"Aligned pointer" means a word whose numeric value (that is, its
value when treated as an unsigned integer) is a multiple of the
architecture's :term:`natural alignment` (see
:c:macro:`MPS_PF_ALIGN`). If you're using a 32-bit architecture,
that means that an aligned pointer is a multiple of 4 and its bottom
two bits are both zero.
value when treated as an unsigned integer) is a multiple of the size
of a pointer. For you're using a 32-bit architecture, that means
that an aligned pointer is a multiple of 4 and its bottom two bits
are both zero.
The bottom line is that references from an object in an AWL pool
must be untagged and aligned, and integers must be tagged with a

Some files were not shown because too many files have changed in this diff Show more