mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-03-26 16:51:46 -07:00
Mps br/vmarenagrow: [work in progress] arenavm.c using gangset, gangs.
Copied from Perforce Change: 164243 ServerID: perforce.ravenbrook.com
This commit is contained in:
parent
b700703795
commit
81ad59fcf6
1 changed files with 381 additions and 154 deletions
|
|
@ -30,27 +30,41 @@
|
|||
SRCID(arenavm, "$Id$");
|
||||
|
||||
/* @@@@ Arbitrary calculations (these should be in config.h) */
|
||||
/* VMArenaGangCount = the maximum number of distinct gangs (ie. */
|
||||
/* ArenaGangCount = the maximum number of distinct gangs (ie. */
|
||||
/* distinct object sets, be they generations or some other group. */
|
||||
/* VMArenaGenCount = the maximum number of distinct generations. */
|
||||
enum {
|
||||
VMArenaGangCount = MPS_WORD_WIDTH,
|
||||
VMArenaGenCount = MPS_WORD_WIDTH/2,
|
||||
VMArenaGenCount = 3 /* @@@@ was MPS_WORD_WIDTH/2 @@@@@@@@@@@@@@@ */,
|
||||
GangIndexDefault = VMArenaGenCount + 0,
|
||||
GangIndexAway = GangIndexDefault + 1
|
||||
GangIndexAway,
|
||||
ArenaGangCount
|
||||
};
|
||||
|
||||
#define GangSig ((Sig)0x5199A499) /* SIGnature GANG */
|
||||
|
||||
typedef struct GangStruct *Gang;
|
||||
|
||||
typedef struct GangsetStruct *Gangset;
|
||||
|
||||
extern void SegPrefZonesOpen(Arena arena, SegPref pref);
|
||||
extern Bool SegPrefZonesNext(ZoneSet *zonesReturn, Arena arena, SegPref pref,
|
||||
Bool pregrow);
|
||||
extern void SegPrefZonesClose(Arena arena, SegPref pref, Bool allocated,
|
||||
Addr base, Addr limit);
|
||||
|
||||
extern Bool GangCheck(Gang gang);
|
||||
extern Res GangDescribe(Gang gang, mps_lib_FILE *stream);
|
||||
extern Bool GangsetCheck(Gangset gangset);
|
||||
|
||||
extern Res GangsetDescribe(Gangset gangset, mps_lib_FILE *stream);
|
||||
static void GangsetInit(Arena arena, Gangset gangset);
|
||||
|
||||
enum {
|
||||
GANGNAMELEN = 4
|
||||
};
|
||||
|
||||
#define GangSig ((Sig)0x5199A499) /* SIGnature GANG */
|
||||
|
||||
typedef struct GangStruct {
|
||||
Index index; /* index in gangset */
|
||||
char name[GANGNAMELEN];
|
||||
ZoneSet preferred;
|
||||
ZoneSet in;
|
||||
|
|
@ -69,16 +83,23 @@ typedef struct GangStruct {
|
|||
* and away from other gangs.
|
||||
*/
|
||||
|
||||
typedef struct Gangset {
|
||||
GangStruct gangs[VMArenaGangCount];
|
||||
#define GangsetSig ((Sig)0x5199A495) /* SIGnature GANGSet */
|
||||
|
||||
typedef struct GangsetStruct {
|
||||
GangStruct gangs[ArenaGangCount];
|
||||
Count gangCount;
|
||||
Count gangGenCount;
|
||||
Index gangIndexDefault; /* index of the default gang */
|
||||
Index gangIndexAway; /* index of the away gang */
|
||||
ZoneSet blacklist; /* zones that are bad for GC segs */
|
||||
ZoneSet freezones; /* unassigned zones */
|
||||
ZoneSet unpreferred; /* zones not preferred by any gang */
|
||||
}
|
||||
ZoneSet freezones; /* unassigned zones */
|
||||
Bool trying; /* is a search for zones in progress? */
|
||||
Index tryingGangIndex;
|
||||
ZoneSet tryingZones;
|
||||
char *tryingWhat;
|
||||
Sig sig; /* <design/sig/> */
|
||||
} GangsetStruct;
|
||||
|
||||
|
||||
/* VMChunk -- chunks for VM arenas */
|
||||
|
|
@ -221,6 +242,8 @@ static Bool VMArenaCheck(VMArena vmArena)
|
|||
/* spare pages are committed, so must be less spare than committed. */
|
||||
CHECKL(vmArena->spareSize <= arena->committed);
|
||||
CHECKL(vmArena->blacklist != ZoneSetUNIV);
|
||||
|
||||
CHECKD(Gangset, &vmArena->gangset);
|
||||
|
||||
allocSet = ZoneSetEMPTY;
|
||||
allocSet = ZoneSetUnion(allocSet, vmArena->uncolZoneSet);
|
||||
|
|
@ -249,7 +272,6 @@ static Res VMArenaDescribe(Arena arena, mps_lib_FILE *stream)
|
|||
{
|
||||
Res res;
|
||||
VMArena vmArena;
|
||||
Index gen;
|
||||
|
||||
if (!CHECKT(Arena, arena)) return ResFAIL;
|
||||
if (stream == NULL) return ResFAIL;
|
||||
|
|
@ -266,6 +288,9 @@ static Res VMArenaDescribe(Arena arena, mps_lib_FILE *stream)
|
|||
*
|
||||
*/
|
||||
|
||||
#if 0
|
||||
{
|
||||
Index gen;
|
||||
res = WriteF(stream,
|
||||
" uncolZoneSet: $B\n",
|
||||
(WriteFB)vmArena->uncolZoneSet,
|
||||
|
|
@ -291,7 +316,13 @@ static Res VMArenaDescribe(Arena arena, mps_lib_FILE *stream)
|
|||
NULL);
|
||||
if(res != ResOK)
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
res = GangsetDescribe(&vmArena->gangset, stream);
|
||||
if(res != ResOK)
|
||||
return res;
|
||||
|
||||
/* (incomplete: some fields are not Described) */
|
||||
|
||||
return ResOK;
|
||||
|
|
@ -510,7 +541,6 @@ static Res VMArenaInit(Arena *arenaReturn, ArenaClass class, va_list args)
|
|||
Res res;
|
||||
VMArena vmArena;
|
||||
Arena arena;
|
||||
Index i;
|
||||
Index gen;
|
||||
VM arenaVM;
|
||||
Chunk chunk;
|
||||
|
|
@ -540,11 +570,12 @@ static Res VMArenaInit(Arena *arenaReturn, ArenaClass class, va_list args)
|
|||
vmArena->vm = arenaVM;
|
||||
vmArena->spareSize = 0;
|
||||
|
||||
GangsetInit(arena, &vmArena->gangset);
|
||||
|
||||
/* .blacklist: We blacklist the zones corresponding to small integers. */
|
||||
vmArena->blacklist =
|
||||
ZoneSetAdd(arena, ZoneSetAdd(arena, ZoneSetEMPTY, (Addr)1), (Addr)-1);
|
||||
|
||||
|
||||
vmArena->uncolZoneSet = ZoneSetEMPTY;
|
||||
vmArena->nogenZoneSet = ZoneSetEMPTY;
|
||||
for(gen = (Index)0; gen < VMArenaGenCount; gen++) {
|
||||
|
|
@ -987,7 +1018,10 @@ static Serial vmGenOfSegPref(VMArena vmArena, SegPref pref)
|
|||
* by other SegPrefs should be considered (if it's FALSE then only
|
||||
* zones already used by this segpref or free zones will be used).
|
||||
*/
|
||||
static Bool pagesFindFreeWithSegPref(Index *baseReturn, VMChunk *chunkReturn,
|
||||
extern Bool pagesFindFreeWithSegPref(Index *baseReturn, VMChunk *chunkReturn,
|
||||
VMArena vmArena, SegPref pref, Size size,
|
||||
Bool barge);
|
||||
Bool pagesFindFreeWithSegPref(Index *baseReturn, VMChunk *chunkReturn,
|
||||
VMArena vmArena, SegPref pref, Size size,
|
||||
Bool barge)
|
||||
{
|
||||
|
|
@ -1163,11 +1197,14 @@ typedef Res (*VMAllocPolicyMethod)(Index *, VMChunk *, VMArena, SegPref, Size);
|
|||
static Res VMAllocPolicy(Index *baseIndexReturn, VMChunk *chunkReturn,
|
||||
VMArena vmArena, SegPref pref, Size size)
|
||||
{
|
||||
Arena arena;
|
||||
ZoneSet zones;
|
||||
|
||||
arena = VMArena2Arena(vmArena);
|
||||
|
||||
for(SegPrefZonesOpen(pref, gangset);
|
||||
SegPrefZonesNext(&zones, pref, TRUE);) {
|
||||
if(pagesFindFreeInZones(baseReturn, chunkReturn, vmArena, size,
|
||||
for(SegPrefZonesOpen(arena, pref);
|
||||
SegPrefZonesNext(&zones, arena, pref, TRUE);) {
|
||||
if(pagesFindFreeInZones(baseIndexReturn, chunkReturn, vmArena, size,
|
||||
zones, pref->high)) {
|
||||
/* Range found, but allocation may still fail; therefore */
|
||||
/* leave the SegPrefZones search unclosed. */
|
||||
|
|
@ -1175,7 +1212,7 @@ static Res VMAllocPolicy(Index *baseIndexReturn, VMChunk *chunkReturn,
|
|||
}
|
||||
}
|
||||
/* end this search, without having allocated */
|
||||
SegPrefZonesClose(FALSE);
|
||||
SegPrefZonesClose(arena, pref, FALSE, NULL, NULL);
|
||||
|
||||
/* try and extend, but don't worry if we can't */
|
||||
(void)vmArenaExtend(vmArena, size);
|
||||
|
|
@ -1184,9 +1221,9 @@ static Res VMAllocPolicy(Index *baseIndexReturn, VMChunk *chunkReturn,
|
|||
/* we proceed to try the allocation again anyway. */
|
||||
/* We specify barging, but if we have got a new chunk */
|
||||
/* then hopefully we won't need to barge. */
|
||||
for(SegPrefZonesOpen(pref, gangset);
|
||||
SegPrefZonesNext(&zones, pref, FALSE);) {
|
||||
if(pagesFindFreeInZones(baseReturn, chunkReturn, vmArena, size,
|
||||
for(SegPrefZonesOpen(arena, pref);
|
||||
SegPrefZonesNext(&zones, arena, pref, FALSE);) {
|
||||
if(pagesFindFreeInZones(baseIndexReturn, chunkReturn, vmArena, size,
|
||||
zones, pref->high)) {
|
||||
/* Range found, but allocation may still fail; therefore */
|
||||
/* leave the SegPrefZones search unclosed. */
|
||||
|
|
@ -1194,7 +1231,7 @@ static Res VMAllocPolicy(Index *baseIndexReturn, VMChunk *chunkReturn,
|
|||
}
|
||||
}
|
||||
/* end this search, without having allocated */
|
||||
SegPrefZonesClose(FALSE);
|
||||
SegPrefZonesClose(arena, pref, FALSE, NULL, NULL);
|
||||
|
||||
/* .improve.alloc-fail: This could be because the request was */
|
||||
/* too large, or perhaps the arena is fragmented. We could */
|
||||
|
|
@ -1205,10 +1242,13 @@ static Res VMAllocPolicy(Index *baseIndexReturn, VMChunk *chunkReturn,
|
|||
static Res VMNZAllocPolicy(Index *baseIndexReturn, VMChunk *chunkReturn,
|
||||
VMArena vmArena, SegPref pref, Size size)
|
||||
{
|
||||
Arena arena = VMArena2Arena(vmArena);
|
||||
SegPrefZonesOpen(arena, pref);
|
||||
if (pagesFindFreeInZones(baseIndexReturn, chunkReturn, vmArena, size,
|
||||
ZoneSetUNIV, pref->high)) {
|
||||
return ResOK;
|
||||
}
|
||||
SegPrefZonesClose(arena, pref, FALSE, NULL, NULL);
|
||||
return ResRESOURCE;
|
||||
}
|
||||
|
||||
|
|
@ -1359,9 +1399,6 @@ static Res vmAllocComm(Addr *baseReturn, Tract *baseTractReturn,
|
|||
Arena arena;
|
||||
Count pages;
|
||||
Index baseIndex;
|
||||
ZoneSet zones;
|
||||
ZoneSet *zsRecord;
|
||||
ZoneSet zsNew;
|
||||
Res res;
|
||||
VMArena vmArena;
|
||||
VMChunk vmChunk;
|
||||
|
|
@ -1421,51 +1458,15 @@ static Res vmAllocComm(Addr *baseReturn, Tract *baseTractReturn,
|
|||
base = PageIndexBase(chunk, baseIndex);
|
||||
baseTract = PageTract(&chunk->pageTable[baseIndex]);
|
||||
limit = AddrAdd(base, size);
|
||||
/* SegPrefGotRange */
|
||||
zones = ZoneSetOfRange(arena, base, limit);
|
||||
|
||||
GangUseZones(gang, zones);
|
||||
if (pref->isGen) {
|
||||
Serial gen = vmGenOfSegPref(vmArena, pref);
|
||||
zsRecord = &vmArena->genZoneSet[gen];
|
||||
}
|
||||
else {
|
||||
zsRecord = &vmArena->nogenZoneSet;
|
||||
}
|
||||
|
||||
zsNew = ZoneSetDiff(zones, *zsRecord);
|
||||
if(zsNew != ZoneSetEMPTY) {
|
||||
/* using a new zone */
|
||||
DIAG_FIRSTF(( "vmAllocComm_newzone", NULL));
|
||||
DIAG( SegPrefDescribe(pref, DIAG_STREAM); );
|
||||
if(pref->isGen) {
|
||||
DIAG_MOREF(( " gen: $U ", (WriteFU)pref->gen, NULL));
|
||||
} else {
|
||||
DIAG_MOREF(( " nogen ", NULL));
|
||||
}
|
||||
DIAG_MOREF((
|
||||
"was: $B ", (WriteFB)*zsRecord,
|
||||
"add: $B\n", (WriteFB)zsNew,
|
||||
NULL));
|
||||
if(!ZoneSetSub(zsNew, vmArena->freeSet)) {
|
||||
DIAG_MOREF(( "BARGE!\n", NULL ));
|
||||
}
|
||||
DIAG_END("vmAllocComm_newzone");
|
||||
|
||||
*zsRecord = ZoneSetUnion(*zsRecord, zones);
|
||||
}
|
||||
|
||||
if(!pref->isCollected) {
|
||||
vmArena->uncolZoneSet = ZoneSetUnion(vmArena->uncolZoneSet, zones);
|
||||
}
|
||||
|
||||
vmArena->freeSet = ZoneSetDiff(vmArena->freeSet, zones);
|
||||
SegPrefZonesClose(arena, pref, TRUE, base, limit);
|
||||
|
||||
*baseReturn = base;
|
||||
*baseTractReturn = baseTract;
|
||||
return ResOK;
|
||||
|
||||
failPagesMap:
|
||||
SegPrefZonesClose(arena, pref, FALSE, NULL, NULL);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -1766,7 +1767,7 @@ mps_arena_class_t mps_arena_class_vmnz(void)
|
|||
|
||||
/* GangCheck */
|
||||
|
||||
static Bool GangCheck(Gang gang)
|
||||
Bool GangCheck(Gang gang)
|
||||
{
|
||||
CHECKS(Gang, gang);
|
||||
CHECKL(gang->name[GANGNAMELEN - 1] == '\0');
|
||||
|
|
@ -1783,6 +1784,8 @@ static Bool GangCheck(Gang gang)
|
|||
Res GangDescribe(Gang gang, mps_lib_FILE *stream)
|
||||
{
|
||||
Res res;
|
||||
Count zones = MPS_WORD_WIDTH;
|
||||
Index zone;
|
||||
|
||||
if(!CHECKT(Gang, gang))
|
||||
return ResFAIL;
|
||||
|
|
@ -1790,13 +1793,32 @@ Res GangDescribe(Gang gang, mps_lib_FILE *stream)
|
|||
return ResFAIL;
|
||||
|
||||
res = WriteF(stream,
|
||||
"Gang $P \"$S\" {\n", (WriteFP)gang, (WriteFS)gang->name,
|
||||
" preferred $B\n", (WriteFB)gang->preferred,
|
||||
" in $B\n", (WriteFB)gang->in,
|
||||
" claimed $B\n", (WriteFB)gang->claimed,
|
||||
" has ", (gang->hasCollected ? "Collected " : ""),
|
||||
(gang->hasUncollected ? "Uncollected " : ""), "\n",
|
||||
" }\n",
|
||||
"Gang $P ($U) \"$S\" ",
|
||||
(WriteFP)gang, (WriteFS)gang->index, (WriteFS)gang->name, NULL);
|
||||
if(res != ResOK)
|
||||
return res;
|
||||
|
||||
zone = zones;
|
||||
do {
|
||||
ZoneSet z = 1 << --zone;
|
||||
Bool in = (ZoneSetInter(z, gang->in) != ZoneSetEMPTY);
|
||||
Bool claimed = (ZoneSetInter(z, gang->claimed) != ZoneSetEMPTY);
|
||||
Bool unique = (ZoneSetInter(z, gang->unique) != ZoneSetEMPTY);
|
||||
res = WriteF(stream,
|
||||
"$S", unique ? (WriteFS)"1"
|
||||
: claimed ? (WriteFS)"c"
|
||||
: in ? (WriteFS)"b"
|
||||
: (WriteFS)".",
|
||||
NULL);
|
||||
if(res != ResOK)
|
||||
return res;
|
||||
} while(zone > 0);
|
||||
|
||||
res = WriteF(stream,
|
||||
" has:", (gang->hasCollected ? "Collected " : ""),
|
||||
(gang->hasUncollected ? "Uncollected " : ""), " ",
|
||||
" (preferred $B)", (WriteFB)gang->preferred,
|
||||
"\n",
|
||||
NULL);
|
||||
if(res != ResOK)
|
||||
return res;
|
||||
|
|
@ -1807,17 +1829,123 @@ Res GangDescribe(Gang gang, mps_lib_FILE *stream)
|
|||
|
||||
/* GANGSET */
|
||||
|
||||
static Bool GangsetCheck(Gang gang)
|
||||
Bool GangsetCheck(Gangset gangset)
|
||||
{
|
||||
Index i;
|
||||
ZoneSet preferred = ZoneSetEMPTY;
|
||||
ZoneSet in = ZoneSetEMPTY;
|
||||
ZoneSet shared = ZoneSetEMPTY;
|
||||
ZoneSet claimed = ZoneSetEMPTY;
|
||||
ZoneSet unique = ZoneSetEMPTY;
|
||||
|
||||
CHECKS(Gangset, gangset);
|
||||
|
||||
CHECKL(gangset->gangCount > 0);
|
||||
for(i = 0; i < gangset->gangCount; i += 1) {
|
||||
Gang gang = &gangset->gangs[i];
|
||||
CHECKD(Gang, gang);
|
||||
CHECKL(gang->index == i);
|
||||
|
||||
CHECKL(ZoneSetInter(preferred, gang->preferred) == ZoneSetEMPTY);
|
||||
preferred = ZoneSetUnion(preferred, gang->preferred);
|
||||
|
||||
shared = ZoneSetUnion(shared, ZoneSetInter(in, gang->in));
|
||||
in = ZoneSetUnion(in, gang->in);
|
||||
|
||||
CHECKL(ZoneSetInter(claimed, gang->claimed) == ZoneSetEMPTY);
|
||||
claimed = ZoneSetUnion(claimed, gang->claimed);
|
||||
CHECKL(ZoneSetInter(unique, gang->unique) == ZoneSetEMPTY);
|
||||
unique = ZoneSetUnion(unique, gang->unique);
|
||||
}
|
||||
CHECKL(ZoneSetInter(shared, unique) == ZoneSetEMPTY);
|
||||
CHECKL(ZoneSetUnion(shared, unique) == in);
|
||||
CHECKL(claimed == in);
|
||||
|
||||
CHECKL(gangset->gangGenCount < gangset->gangCount);
|
||||
CHECKL(gangset->gangIndexDefault >= gangset->gangGenCount);
|
||||
CHECKL(gangset->gangIndexDefault < gangset->gangCount);
|
||||
CHECKL(gangset->gangIndexAway >= gangset->gangGenCount);
|
||||
CHECKL(gangset->gangIndexAway != gangset->gangIndexDefault);
|
||||
CHECKL(gangset->gangIndexAway < gangset->gangCount);
|
||||
CHECKL(gangset->blacklist != ZoneSetUNIV);
|
||||
CHECKL(gangset->unpreferred == ZoneSetComp(preferred));
|
||||
CHECKL(gangset->freezones == ZoneSetComp(in));
|
||||
|
||||
CHECKL(BoolCheck(gangset->trying));
|
||||
if(gangset->trying) {
|
||||
CHECKL(gangset->tryingGangIndex < gangset->gangCount);
|
||||
/* no check for tryingZones */
|
||||
/* no check for tryingWhat */
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Res GangsetInit(Gangset gangset)
|
||||
Res GangsetDescribe(Gangset gangset, mps_lib_FILE *stream)
|
||||
{
|
||||
Res res;
|
||||
Index i;
|
||||
|
||||
if(!CHECKT(Gangset, gangset))
|
||||
return ResFAIL;
|
||||
if(stream == NULL)
|
||||
return ResFAIL;
|
||||
|
||||
res = WriteF(stream,
|
||||
"Gangset $P {\n", (WriteFP)gangset,
|
||||
NULL);
|
||||
if(res != ResOK)
|
||||
return res;
|
||||
|
||||
for(i = 0; i < gangset->gangCount; i += 1) {
|
||||
res = GangDescribe(&gangset->gangs[i], stream);
|
||||
if(res != ResOK)
|
||||
return res;
|
||||
}
|
||||
|
||||
res = WriteF(stream,
|
||||
" blacklist: $B\n", (WriteFB)gangset->blacklist,
|
||||
"unpreferred: $B\n", (WriteFB)gangset->unpreferred,
|
||||
" freezones: $B\n", (WriteFB)gangset->freezones,
|
||||
NULL);
|
||||
if(res != ResOK)
|
||||
return res;
|
||||
|
||||
if(gangset->trying) {
|
||||
res = WriteF(stream,
|
||||
" Trying: GangIndex $U Zones $B $S\n",
|
||||
(WriteFU)gangset->tryingGangIndex,
|
||||
(WriteFB)gangset->tryingZones,
|
||||
(WriteFS)(gangset->tryingWhat == NULL ? "" : gangset->tryingWhat),
|
||||
NULL);
|
||||
} else {
|
||||
res = WriteF(stream,
|
||||
" (not trying)\n",
|
||||
NULL);
|
||||
}
|
||||
if(res != ResOK)
|
||||
return res;
|
||||
|
||||
res = WriteF(stream,
|
||||
"}\n",
|
||||
NULL);
|
||||
if(res != ResOK)
|
||||
return res;
|
||||
|
||||
return ResOK;
|
||||
}
|
||||
|
||||
|
||||
static void GangsetInit(Arena arena, Gangset gangset)
|
||||
{
|
||||
ZoneSet preferred = ZoneSetEMPTY;
|
||||
Index i;
|
||||
|
||||
DIAG_FIRSTF(( "GangsetInit", NULL ));
|
||||
for(i = 0; i < VMArenaGangCount; i += 1) {
|
||||
for(i = 0; i < ArenaGangCount; i += 1) {
|
||||
Gang gang;
|
||||
gang = &vmArena->gangs[i];
|
||||
gang = &gangset->gangs[i];
|
||||
gang->index = i;
|
||||
gang->name[0] = '\0';
|
||||
gang->name[1] = '\0';
|
||||
gang->name[2] = '\0';
|
||||
|
|
@ -1832,19 +1960,21 @@ static Res GangsetInit(Gangset gangset)
|
|||
/* pre-made gangs for generations */
|
||||
gang->name[0] = 'g';
|
||||
gang->name[1] = '0' + i;
|
||||
gang->name[2] = ' ';
|
||||
} else if(i == GangIndexDefault) {
|
||||
/* nogen default-zoneset: Gang Default */
|
||||
gang->name[0] = 'd';
|
||||
gang->name[1] = 'e';
|
||||
gang->name[2] = 'f';
|
||||
/* note: we do NOT set preferred to ArenaDefaultZONESET */
|
||||
gangset->gangIndexDefault = GangIndexDefault;
|
||||
} else if(i == GangIndexAway) {
|
||||
/* nogen non-default-zoneset: Gang Away */
|
||||
gang->name[0] = 'a';
|
||||
gang->name[1] = 'w';
|
||||
gang->name[2] = 'y';
|
||||
if(ArenaDefaultZONESET != ZoneSetUNIV)
|
||||
gang->preferred = ZoneSetComp(ArenaDefaultZONESET);
|
||||
gang->preferred = ZoneSetComp(ArenaDefaultZONESET);
|
||||
gangset->gangIndexAway = GangIndexAway;
|
||||
} else {
|
||||
/* unused gang */
|
||||
gang->name[0] = 'x';
|
||||
|
|
@ -1852,57 +1982,112 @@ static Res GangsetInit(Gangset gangset)
|
|||
gang->sig = GangSig;
|
||||
AVERT(Gang, gang);
|
||||
DIAG( GangDescribe(gang, DIAG_STREAM); );
|
||||
preferred = ZoneSetUnion(preferred, gang->preferred);
|
||||
}
|
||||
AVER(i == VMArenaGangCount);
|
||||
AVER(i == ArenaGangCount);
|
||||
gangset->gangCount = i;
|
||||
gangset->gangGenCount = VMArenaGenCount;
|
||||
|
||||
/* .blacklist: We blacklist the zones corresponding to small integers. */
|
||||
gangset->blacklist =
|
||||
ZoneSetAdd(arena, ZoneSetAdd(arena, ZoneSetEMPTY, (Addr)1), (Addr)-1);
|
||||
|
||||
gangset->freezones = ZoneSetUNIV;
|
||||
gangset->unpreferred = ZoneSetComp(preferred);
|
||||
gangset->trying = FALSE;
|
||||
|
||||
gangset->sig = GangsetSig;
|
||||
AVERT(Gangset, gangset);
|
||||
DIAG_END("GangsetInit");
|
||||
}
|
||||
|
||||
void SegPrefZonesOpen(SegPref pref, Gangset gangset)
|
||||
|
||||
/* SegPrefZonesOpen -- start a search for zones for this SegPref
|
||||
*
|
||||
* Usage:
|
||||
* - for(SegPrefZonesOpen; SegPrefZonesNext(&zones); ) {
|
||||
* - attempt to allocate in zones;
|
||||
* - SegPrefZonesClose, with allocated = True or False.
|
||||
*
|
||||
* Every search started with SegPrefZonesOpen must be ended with a
|
||||
* call to SegPrefZonesClose (once it is known whether or not a
|
||||
* range of memory has been successfully allocated).
|
||||
*
|
||||
* Currently, only one such search may be in progress at a time.
|
||||
* This is sufficient and simple. (It would be easy to allow
|
||||
* multiple simultaneous searches if that becomes necessary).
|
||||
*
|
||||
* The state of the search is recorded in the gangset. This gives
|
||||
* us a place to store arbitrary state, and lets us verify that
|
||||
* each SegPrefZonesOpen is followed by a SegPrefZonesClose.
|
||||
*/
|
||||
|
||||
void SegPrefZonesOpen(Arena arena, SegPref pref)
|
||||
{
|
||||
VMArena vmArena;
|
||||
Gangset gangset;
|
||||
Index gangIndex;
|
||||
|
||||
AVERT(Gangset, gangset);
|
||||
AVERT(Arena, arena);
|
||||
AVERT(SegPref, pref);
|
||||
vmArena = Arena2VMArena(arena);
|
||||
AVERT(VMArena, vmArena);
|
||||
gangset = &vmArena->gangset;
|
||||
/* gangset = &arena->gangset; */
|
||||
AVERT(Gangset, gangset);
|
||||
|
||||
AVER(pref->gangset == NULL);
|
||||
AVER(pref->gangIndex == NULL);
|
||||
AVER(pref->trying == ZoneSetEMPTY);
|
||||
AVER(!gangset->trying);
|
||||
|
||||
if(pref->isGen) {
|
||||
gangIndex = pref->gen;
|
||||
if(gangIndex > VMArenaGenCount) {
|
||||
gangIndex = VMArenaGenCount;
|
||||
}
|
||||
} else if(pref->zones == ArenaDefaultZONESET) {
|
||||
gangIndex = GangIndexDefault;
|
||||
} else {
|
||||
/* for now, all other preferences are lump together in */
|
||||
/* for now, all other preferences are lumped together in */
|
||||
/* the "Away" gang */
|
||||
gangIndex = GangIndexAway;
|
||||
}
|
||||
AVERT(Gang, gangset->gangs[gangIndex]);
|
||||
AVERT(Gang, &gangset->gangs[gangIndex]);
|
||||
|
||||
pref->gangset = gangset;
|
||||
pref->gangIndex = gangIndex;
|
||||
pref->trying = ZoneSetEMPTY;
|
||||
gangset->trying = TRUE;
|
||||
gangset->tryingGangIndex = gangIndex;
|
||||
gangset->tryingZones = ZoneSetEMPTY;
|
||||
gangset->tryingWhat = NULL;
|
||||
}
|
||||
|
||||
|
||||
Bool SegPrefZonesNext(ZoneSet *zonesReturn, SegPref pref, Bool pregrow)
|
||||
Bool SegPrefZonesNext(ZoneSet *zonesReturn, Arena arena, SegPref pref,
|
||||
Bool pregrow)
|
||||
{
|
||||
VMArena vmArena;
|
||||
Gangset gangset;
|
||||
Index gangIndex;
|
||||
Gang gang;
|
||||
ZoneSet bl;
|
||||
ZoneSet extra;
|
||||
ZoneSet zones;
|
||||
char *t;
|
||||
Bool newzones;
|
||||
|
||||
AVERT(Arena, arena);
|
||||
AVERT(SegPref, pref);
|
||||
AVER(pref->gangset);
|
||||
gangset = pref->gangset;
|
||||
AVER(BoolCheck(pregrow));
|
||||
|
||||
vmArena = Arena2VMArena(arena);
|
||||
AVERT(VMArena, vmArena);
|
||||
gangset = &vmArena->gangset;
|
||||
/* gangset = &arena->gangset; */
|
||||
AVERT(Gangset, gangset);
|
||||
AVER(pref->gangIndex < gangset->gangCount);
|
||||
gang = gangset->gangs[pref->gangIndex];
|
||||
|
||||
AVER(gangset->trying);
|
||||
AVER(gangset->tryingGangIndex < gangset->gangCount);
|
||||
gang = &gangset->gangs[gangset->tryingGangIndex];
|
||||
AVERT(Gang, gang);
|
||||
|
||||
bl = gangset->blacklist;
|
||||
zones = pref->trying;
|
||||
zones = gangset->tryingZones;
|
||||
newzones = TRUE;
|
||||
|
||||
/* For simplicity, we insist that each successive set of zones to
|
||||
|
|
@ -1938,45 +2123,45 @@ Bool SegPrefZonesNext(ZoneSet *zonesReturn, SegPref pref, Bool pregrow)
|
|||
t = "in my current unique zones (& my preferred)";
|
||||
extra = ZoneSetInter(gang->unique, gang->preferred);
|
||||
zones = ZoneSetUnion(zones, ZoneSetDiff(extra, bl));
|
||||
if(!ZoneSetSub(zones, pref->trying))
|
||||
if(!ZoneSetSub(zones, gangset->tryingZones))
|
||||
break;
|
||||
|
||||
t = "in my current unique zones";
|
||||
extra = gang->unique;
|
||||
zones = ZoneSetUnion(zones, ZoneSetDiff(extra, bl));
|
||||
if(!ZoneSetSub(zones, pref->trying))
|
||||
if(!ZoneSetSub(zones, gangset->tryingZones))
|
||||
break;
|
||||
|
||||
/* Shared(claimed) */
|
||||
t = "use a shared claimed zone (& my preferred)";
|
||||
extra = ZoneSetInter(gang->claimed, gang->preferred);
|
||||
zones = ZoneSetUnion(zones, ZoneSetDiff(extra, bl));
|
||||
if(!ZoneSetSub(zones, pref->trying))
|
||||
if(!ZoneSetSub(zones, gangset->tryingZones))
|
||||
break;
|
||||
|
||||
t = "use a shared claimed zone";
|
||||
extra = gang->claimed;
|
||||
zones = ZoneSetUnion(zones, ZoneSetDiff(extra, bl));
|
||||
if(!ZoneSetSub(zones, pref->trying))
|
||||
if(!ZoneSetSub(zones, gangset->tryingZones))
|
||||
break;
|
||||
|
||||
/* Free zone -- these can be slow */
|
||||
t = "add a free zone (my preferred)";
|
||||
extra = ZoneSetInter(gangset->freezones, gang->preferred);
|
||||
zones = ZoneSetUnion(zones, ZoneSetDiff(extra, bl));
|
||||
if(!ZoneSetSub(zones, pref->trying))
|
||||
if(!ZoneSetSub(zones, gangset->tryingZones))
|
||||
break;
|
||||
|
||||
t = "add a free zone (unpreferred)";
|
||||
extra = ZoneSetInter(gangset->freezones, gangset->unpreferred);
|
||||
zones = ZoneSetUnion(zones, ZoneSetDiff(extra, bl));
|
||||
if(!ZoneSetSub(zones, pref->trying))
|
||||
if(!ZoneSetSub(zones, gangset->tryingZones))
|
||||
break;
|
||||
|
||||
t = "add a free zone (even other gang's preferred)";
|
||||
extra = gangset->freezones;
|
||||
zones = ZoneSetUnion(zones, ZoneSetDiff(extra, bl));
|
||||
if(!ZoneSetSub(zones, pref->trying))
|
||||
if(!ZoneSetSub(zones, gangset->tryingZones))
|
||||
break;
|
||||
|
||||
/* Shared(borrowed) */
|
||||
|
|
@ -1984,13 +2169,13 @@ Bool SegPrefZonesNext(ZoneSet *zonesReturn, SegPref pref, Bool pregrow)
|
|||
t = "use a shared borrowed zone (& my preferred)";
|
||||
extra = ZoneSetInter(gang->in, gang->preferred);
|
||||
zones = ZoneSetUnion(zones, ZoneSetDiff(extra, bl));
|
||||
if(!ZoneSetSub(zones, pref->trying))
|
||||
if(!ZoneSetSub(zones, gangset->tryingZones))
|
||||
break;
|
||||
|
||||
t = "use a shared borrowed zone";
|
||||
extra = gang->in;
|
||||
zones = ZoneSetUnion(zones, ZoneSetDiff(extra, bl));
|
||||
if(!ZoneSetSub(zones, pref->trying))
|
||||
if(!ZoneSetSub(zones, gangset->tryingZones))
|
||||
break;
|
||||
|
||||
t = "grow";
|
||||
|
|
@ -2006,12 +2191,12 @@ Bool SegPrefZonesNext(ZoneSet *zonesReturn, SegPref pref, Bool pregrow)
|
|||
/* @@@@ should first try the zone with most free grains */
|
||||
extra = ZoneSetUNIV;
|
||||
zones = ZoneSetUnion(zones, ZoneSetDiff(extra, bl));
|
||||
if(!ZoneSetSub(zones, pref->trying))
|
||||
if(!ZoneSetSub(zones, gangset->tryingZones))
|
||||
break;
|
||||
|
||||
t = "allow blacklist";
|
||||
zones = ZoneSetUNIV;
|
||||
if(!ZoneSetSub(zones, pref->trying))
|
||||
if(!ZoneSetSub(zones, gangset->tryingZones))
|
||||
break;
|
||||
|
||||
t = "no more zones to try";
|
||||
|
|
@ -2042,19 +2227,19 @@ Bool SegPrefZonesNext(ZoneSet *zonesReturn, SegPref pref, Bool pregrow)
|
|||
extra = ZoneSetInter(gang->unique, gang->preferred);
|
||||
extra = ZoneSetInter(extra, bl);
|
||||
zones = ZoneSetUnion(zones, extra);
|
||||
if(!ZoneSetSub(zones, pref->trying))
|
||||
if(!ZoneSetSub(zones, gangset->tryingZones))
|
||||
break;
|
||||
|
||||
t = "in my current unique zones (& my preferred)";
|
||||
extra = ZoneSetInter(gang->unique, gang->preferred);
|
||||
zones = ZoneSetUnion(zones, extra);
|
||||
if(!ZoneSetSub(zones, pref->trying))
|
||||
if(!ZoneSetSub(zones, gangset->tryingZones))
|
||||
break;
|
||||
|
||||
t = "in my current unique zones";
|
||||
extra = gang->unique;
|
||||
zones = ZoneSetUnion(zones, extra);
|
||||
if(!ZoneSetSub(zones, pref->trying))
|
||||
if(!ZoneSetSub(zones, gangset->tryingZones))
|
||||
break;
|
||||
|
||||
/* Shared(claimed) */
|
||||
|
|
@ -2062,19 +2247,19 @@ Bool SegPrefZonesNext(ZoneSet *zonesReturn, SegPref pref, Bool pregrow)
|
|||
extra = ZoneSetInter(gang->claimed, gang->preferred);
|
||||
extra = ZoneSetInter(extra, bl);
|
||||
zones = ZoneSetUnion(zones, extra);
|
||||
if(!ZoneSetSub(zones, pref->trying))
|
||||
if(!ZoneSetSub(zones, gangset->tryingZones))
|
||||
break;
|
||||
|
||||
t = "use a shared claimed zone (& my preferred)";
|
||||
extra = ZoneSetInter(gang->claimed, gang->preferred);
|
||||
zones = ZoneSetUnion(zones, extra);
|
||||
if(!ZoneSetSub(zones, pref->trying))
|
||||
if(!ZoneSetSub(zones, gangset->tryingZones))
|
||||
break;
|
||||
|
||||
t = "use a shared claimed zone";
|
||||
extra = gang->claimed;
|
||||
zones = ZoneSetUnion(zones, extra);
|
||||
if(!ZoneSetSub(zones, pref->trying))
|
||||
if(!ZoneSetSub(zones, gangset->tryingZones))
|
||||
break;
|
||||
|
||||
/* Free zone -- these can be slow */
|
||||
|
|
@ -2082,39 +2267,39 @@ Bool SegPrefZonesNext(ZoneSet *zonesReturn, SegPref pref, Bool pregrow)
|
|||
extra = ZoneSetInter(gangset->freezones, gang->preferred);
|
||||
extra = ZoneSetInter(extra, bl);
|
||||
zones = ZoneSetUnion(zones, extra);
|
||||
if(!ZoneSetSub(zones, pref->trying))
|
||||
if(!ZoneSetSub(zones, gangset->tryingZones))
|
||||
break;
|
||||
|
||||
t = "add a free zone (my preferred)";
|
||||
extra = ZoneSetInter(gangset->freezones, gang->preferred);
|
||||
zones = ZoneSetUnion(zones, extra);
|
||||
if(!ZoneSetSub(zones, pref->trying))
|
||||
if(!ZoneSetSub(zones, gangset->tryingZones))
|
||||
break;
|
||||
|
||||
t = "add a free zone (unpreferred & blacklist)";
|
||||
extra = ZoneSetInter(gangset->freezones, gangset->unpreferred);
|
||||
extra = ZoneSetInter(extra, bl);
|
||||
zones = ZoneSetUnion(zones, extra);
|
||||
if(!ZoneSetSub(zones, pref->trying))
|
||||
if(!ZoneSetSub(zones, gangset->tryingZones))
|
||||
break;
|
||||
|
||||
t = "add a free zone (unpreferred)";
|
||||
extra = ZoneSetInter(gangset->freezones, gangset->unpreferred);
|
||||
zones = ZoneSetUnion(zones, extra);
|
||||
if(!ZoneSetSub(zones, pref->trying))
|
||||
if(!ZoneSetSub(zones, gangset->tryingZones))
|
||||
break;
|
||||
|
||||
t = "add a free zone (even other gang's preferred, & blacklist)";
|
||||
extra = gangset->freezones;
|
||||
extra = ZoneSetInter(extra, bl);
|
||||
zones = ZoneSetUnion(zones, extra);
|
||||
if(!ZoneSetSub(zones, pref->trying))
|
||||
if(!ZoneSetSub(zones, gangset->tryingZones))
|
||||
break;
|
||||
|
||||
t = "add a free zone (even other gang's preferred)";
|
||||
extra = gangset->freezones;
|
||||
zones = ZoneSetUnion(zones, extra);
|
||||
if(!ZoneSetSub(zones, pref->trying))
|
||||
if(!ZoneSetSub(zones, gangset->tryingZones))
|
||||
break;
|
||||
|
||||
/* Shared(borrowed) */
|
||||
|
|
@ -2123,29 +2308,29 @@ Bool SegPrefZonesNext(ZoneSet *zonesReturn, SegPref pref, Bool pregrow)
|
|||
extra = ZoneSetInter(gang->in, gang->preferred);
|
||||
extra = ZoneSetInter(extra, bl);
|
||||
zones = ZoneSetUnion(zones, extra);
|
||||
if(!ZoneSetSub(zones, pref->trying))
|
||||
if(!ZoneSetSub(zones, gangset->tryingZones))
|
||||
break;
|
||||
|
||||
t = "use a shared borrowed zone (& my preferred)";
|
||||
extra = ZoneSetInter(gang->in, gang->preferred);
|
||||
zones = ZoneSetUnion(zones, extra);
|
||||
if(!ZoneSetSub(zones, pref->trying))
|
||||
if(!ZoneSetSub(zones, gangset->tryingZones))
|
||||
break;
|
||||
|
||||
t = "use a shared borrowed zone (& blacklist)";
|
||||
extra = gang->in;
|
||||
extra = ZoneSetInter(extra, bl);
|
||||
zones = ZoneSetUnion(zones, extra);
|
||||
if(!ZoneSetSub(zones, pref->trying))
|
||||
if(!ZoneSetSub(zones, gangset->tryingZones))
|
||||
break;
|
||||
|
||||
t = "use a shared borrowed zone";
|
||||
extra = gang->in;
|
||||
zones = ZoneSetUnion(zones, extra);
|
||||
if(!ZoneSetSub(zones, pref->trying))
|
||||
if(!ZoneSetSub(zones, gangset->tryingZones))
|
||||
break;
|
||||
|
||||
t = "grow";
|
||||
t = "time to grow arena, to avoid barging";
|
||||
if(pregrow) {
|
||||
newzones = FALSE;
|
||||
break;
|
||||
|
|
@ -2155,14 +2340,14 @@ Bool SegPrefZonesNext(ZoneSet *zonesReturn, SegPref pref, Bool pregrow)
|
|||
extra = ZoneSetUNIV;
|
||||
extra = ZoneSetInter(extra, bl);
|
||||
zones = ZoneSetUnion(zones, extra);
|
||||
if(!ZoneSetSub(zones, pref->trying))
|
||||
if(!ZoneSetSub(zones, gangset->tryingZones))
|
||||
break;
|
||||
|
||||
t = "barge into another gang's zone";
|
||||
/* @@@@ should first try the zone with most free grains */
|
||||
extra = ZoneSetUNIV;
|
||||
zones = ZoneSetUnion(zones, extra);
|
||||
if(!ZoneSetSub(zones, pref->trying))
|
||||
if(!ZoneSetSub(zones, gangset->tryingZones))
|
||||
break;
|
||||
|
||||
t = "no more zones to try";
|
||||
|
|
@ -2173,18 +2358,28 @@ Bool SegPrefZonesNext(ZoneSet *zonesReturn, SegPref pref, Bool pregrow)
|
|||
|
||||
}
|
||||
|
||||
gangset->tryingWhat = t;
|
||||
if(newzones) {
|
||||
/* AVER(zones > pref->trying) */
|
||||
AVER(ZoneSetSuper(zones, pref->trying));
|
||||
AVER(zones != pref->trying);
|
||||
pref->trying = zones;
|
||||
/* AVER(zones > gangset->tryingZones) */
|
||||
AVER(ZoneSetSuper(zones, gangset->tryingZones));
|
||||
AVER(zones != gangset->tryingZones);
|
||||
gangset->tryingZones = zones;
|
||||
*zonesReturn = zones;
|
||||
|
||||
DIAG_SINGLEF(( "SegPrefZonesNext",
|
||||
"gang \"$S\" ", (WriteFS)gang->name,
|
||||
"$S: zones = $B", (WriteFS)t, (WriteFB)zones, NULL ));
|
||||
} else {
|
||||
DIAG_SINGLEF(( "SegPrefZonesNext",
|
||||
"gang \"$S\" ", (WriteFS)gang->name,
|
||||
"$S (newzones = Empty)\n", (WriteFS)t, NULL ));
|
||||
}
|
||||
|
||||
return newzones;
|
||||
}
|
||||
|
||||
|
||||
/* SegPrefZonesClose -- finished search for zones for this SegPref
|
||||
/* SegPrefZonesClose -- end the search for zones for this SegPref
|
||||
*
|
||||
* For each search started with SegPrefZonesOpen, there must be one
|
||||
* matching call to SegPrefZonesClose, before the next call to
|
||||
|
|
@ -2205,57 +2400,89 @@ Bool SegPrefZonesNext(ZoneSet *zonesReturn, SegPref pref, Bool pregrow)
|
|||
* (eg. OS refuses to map more pages).
|
||||
*/
|
||||
|
||||
void SegPrefZonesClose(Arena arena, SegPref pref, Bool allocated, Addr base, Addr limit)
|
||||
void SegPrefZonesClose(Arena arena, SegPref pref, Bool allocated,
|
||||
Addr base, Addr limit)
|
||||
{
|
||||
VMArena vmArena;
|
||||
ZoneSet zones;
|
||||
ZoneSet zonesNew;
|
||||
Gangset gangset;
|
||||
Gang gang;
|
||||
|
||||
AVERT(Arena, arena);
|
||||
AVERT(SegPref, pref);
|
||||
AVER(limit > base);
|
||||
AVER(BoolCheck(allocated));
|
||||
/* base & limit checked later */
|
||||
|
||||
vmArena = Arena2VMArena(arena);
|
||||
AVERT(VMArena, vmArena);
|
||||
gangset = &vmArena->gangset;
|
||||
/* gangset = &arena->gangset; */
|
||||
AVERT(Gangset, gangset);
|
||||
|
||||
AVER(gangset->trying);
|
||||
AVER(gangset->tryingGangIndex < gangset->gangCount);
|
||||
gang = &gangset->gangs[gangset->tryingGangIndex];
|
||||
AVERT(Gang, gang);
|
||||
|
||||
if(!allocated) {
|
||||
/* this search was abandoned */
|
||||
AVER(base == NULL);
|
||||
AVER(limit == NULL);
|
||||
gangset->trying = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
AVER(base < limit);
|
||||
zones = ZoneSetOfRange(arena, base, limit);
|
||||
|
||||
AVER(pref->gangset);
|
||||
gang = pref->gangset->gangs[pref->gangIndex];
|
||||
AVERT(Gang, gang);
|
||||
zonesNew = ZoneSetDiff(zones, gang->in);
|
||||
if(zonesNew != ZoneSetEMPTY) {
|
||||
Index i;
|
||||
|
||||
zsNew = ZoneSetDiff(zones, gang->in);
|
||||
if(zsNew != ZoneSetEMPTY) {
|
||||
/* using a new zone */
|
||||
|
||||
DIAG_FIRSTF(( "SegPrefGotRange_newzone", NULL));
|
||||
/* Using a new zone. */
|
||||
DIAG_FIRSTF(( "SegPrefZonesClose_newzone", NULL));
|
||||
DIAG( SegPrefDescribe(pref, DIAG_STREAM); );
|
||||
if(pref->isGen) {
|
||||
DIAG_MOREF(( " gen: $U ", (WriteFU)pref->gen, NULL));
|
||||
} else {
|
||||
DIAG_MOREF(( " nogen ", NULL));
|
||||
}
|
||||
DIAG_MOREF((
|
||||
"was: $B ", (WriteFB)gang->in,
|
||||
"add: $B\n", (WriteFB)zsNew,
|
||||
"add: $B\n", (WriteFB)zonesNew,
|
||||
NULL));
|
||||
if(!ZoneSetSub(zsNew, vmArena->freeSet)) {
|
||||
if(!ZoneSetSub(zonesNew, gangset->freezones)) {
|
||||
DIAG_MOREF(( "BARGE!\n", NULL ));
|
||||
}
|
||||
DIAG_END("SegPrefGotRange_newzone");
|
||||
DIAG_END("SegPrefZonesClose_newzone");
|
||||
|
||||
gang->in = ZoneSetUnion(gang->in, zsNew);
|
||||
gang->claimed = ZoneSetUnion(gang->claimed, zsNew);
|
||||
gang->unique = ZoneSetUnion(gang->unique, zsNew);
|
||||
for(i = 0; i < VMArenaGangCount; i += 1) {
|
||||
gang->in = ZoneSetUnion(gang->in, zonesNew);
|
||||
/* Are zonesNew claimed and unique for this gang? Assume yes... */
|
||||
gang->claimed = ZoneSetUnion(gang->claimed, zonesNew);
|
||||
gang->unique = ZoneSetUnion(gang->unique, zonesNew);
|
||||
for(i = 0; i < ArenaGangCount; i += 1) {
|
||||
/* ... unless we find some other gang already using them. */
|
||||
Gang other;
|
||||
other = &vmArena->gangs[i];
|
||||
ZoneSet newclash;
|
||||
other = &gangset->gangs[i];
|
||||
if(other == gang)
|
||||
continue;
|
||||
newclash = ZoneSetInter(zsNew, other->in);
|
||||
newclash = ZoneSetInter(zonesNew, other->in);
|
||||
if(newclash != ZoneSetEMPTY) {
|
||||
gang->claimed = ZoneSetDiff(gang->claimed, newclash);
|
||||
gang->unique = ZoneSetDiff(gang->unique, newclash);
|
||||
other->unique = ZoneSetDiff(other->unique, newclash);
|
||||
}
|
||||
}
|
||||
gangset->freezones = ZoneSetDiff(gangset->freezones, zonesNew);
|
||||
|
||||
AVERT(Gangset, gangset);
|
||||
}
|
||||
|
||||
if(pref->isCollected) {
|
||||
gang->hasCollected = TRUE;
|
||||
} else {
|
||||
gang->hasUncollected = TRUE;
|
||||
}
|
||||
|
||||
gangset->trying = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue