[Pntool-developers] SF.net SVN: pntool:[226] spnbox
Brought to you by:
compaqdrew,
miordache
From: <Ste...@us...> - 2009-08-20 13:40:42
|
Revision: 226 http://pntool.svn.sourceforge.net/pntool/?rev=226&view=rev Author: StephenCamp Date: 2009-08-20 13:40:31 +0000 (Thu, 20 Aug 2009) Log Message: ----------- Changed the array allocation optimizing functions in MemoryManager to make the interface more consistent. Modified invar to use the new function definitions. Removed "ID", a debugging parameter, from Dp and Dp4 source and from the test routines. Modified Dp to use the MemoryGrower functions for its arrays which constantly change length. MemoryGrower uses large block allocations to minimize the number of times that new memory actually has to be allocated. Memwatch linking is ON in this test Makefile version. Modified Paths: -------------- spnbox/MemoryManager.c spnbox/MemoryManager.h spnbox/dp.c spnbox/dp4.c spnbox/invar.c spnbox/spnbox.h spnbox/tests/Makefile spnbox/tests/test-dp.c spnbox/tests/test-dp.txt Modified: spnbox/MemoryManager.c =================================================================== --- spnbox/MemoryManager.c 2009-08-19 15:49:09 UTC (rev 225) +++ spnbox/MemoryManager.c 2009-08-20 13:40:31 UTC (rev 226) @@ -127,64 +127,64 @@ return g; } -/*GetGrowableMemory gets some memory that can grow.*/ -void* GetGrowableMemory(MemoryGrower* g, int size) +void* growMalloc(MemoryGrower* g, void* memory, int size) { + /*If the pointer is null, allocate some new memory.*/ if (! g) { - merror(0, "GETGROWABLEMEMORY: Required parameter is null"); + merror(0, "MEMORYGROWER: The pointer to the grower is null"); return 0; - } - if (g->next == g->memories) - { - merror(0, "GETGROWABLEMEMORY: Too many pointers in memory"); - return 0; } - if (size < g->blocksize) size = g->blocksize; - g->memory[g->next] = tmalloc(size); - g->capacity[g->next] = size; - return g->memory[g->next++]; -} - -/*GrowMemory increases the capacity of the given piece of memory. Raises -a fatal error if the memory has not been registered with it.*/ -void* GrowMemory(MemoryGrower* g, void* memory, int newCapacity) -{ - if (! (g && memory)) + if (! memory) { - merror(0, "GROWMEMORY: Required pointer is null"); - return 0; + if (g->next == g->memories) + { + merror(0, "MEMORYGROWER: Too many pointers registered with the grower"); + return 0; + } + if (size < g->blocksize) size = g->blocksize; + g->memory[g->next] = tmalloc(size); + g->capacity[g->next] = size; + return g->memory[g->next++]; } - /*Find the memory.*/ - int i; - for (i = 0; i < g->next; i++) - { - if (memory == g->memory[i]) break; - } - if (i == g->next) - { - merror(0, "GROWMEMORY: The memory did not originate with the grower"); - return 0; - } - /*If we are still within the allocated capacity, return the memory - as-is.*/ - if (newCapacity <= g->capacity[i]) - { - return memory; - } - /*Otherwise, allocate some new memory.*/ else { - if (newCapacity < g->capacity[i] + g->blocksize) newCapacity = g->capacity[i] + g->blocksize; - void* newMem = tmalloc(newCapacity); - memcpy(newMem, memory, g->capacity[i]); - g->capacity[i] = newCapacity; - g->memory[i] = newMem; - free(memory); - return newMem; + /*Otherwise, find the index of the memory record.*/ + int i; + for (i = 0; i < g->next; i++) + { + if (memory == g->memory[i]) break; + } + if (i == g->next) + { + merror(0, "MEMORYGROWER: The memory did not originate with the grower"); + return 0; + } + /*If the request size is smaller than the current capacity return without + reallocating.*/ + if (size < g->capacity[i]) + { + return memory; + } + /*Otherwise, allocate as necessary.*/ + { + if (size < g->capacity[i] + g->blocksize) size = g->capacity[i] + g->blocksize; + void* newMem = tmalloc(size); + memcpy(newMem, memory, g->capacity[i]); + g->capacity[i] = size; + g->memory[i] = newMem; + free(memory); + return newMem; + } } } +void* growCalloc(MemoryGrower* g, void* memory, int elementSize, int elements) +{ + return growMalloc(g, memory, elementSize * elements); +} + + /*FreeMemoryGrower deallocates all the memories pointed to by a memory grower.*/ void FreeMemoryGrower(MemoryGrower* g) Modified: spnbox/MemoryManager.h =================================================================== --- spnbox/MemoryManager.h 2009-08-19 15:49:09 UTC (rev 225) +++ spnbox/MemoryManager.h 2009-08-20 13:40:31 UTC (rev 226) @@ -62,14 +62,13 @@ /*CreateMemoryGrower initializes a memory grower structure.*/ MemoryGrower CreateMemoryGrower(int pointers, int blocksize); -/*GetGrowableMemory gets some memory that can grow.*/ -void* GetGrowableMemory(MemoryGrower* g, int size); +/*growMalloc and growCalloc grow the specified piece of memory to the given +capacity. If the pointer to the memory is null, new memory is allocated. If the +pointer points to a piece of memory the memorygrower is not responsible for the +function fails.*/ +void* growMalloc(MemoryGrower* g, void* memory, int size); +void* growCalloc(MemoryGrower* g, void* memory, int elementSize, int elements); -/*GrowMemory increases the capacity of the given piece of memory. Raises -a fatal error if the memory has not been registered with the memory -grower.*/ -void* GrowMemory(MemoryGrower* g, void* memory, int newCapacity); - /*FreeMemoryGrower deallocates all the memories pointed to by a memory grower.*/ void FreeMemoryGrower(MemoryGrower* g); Modified: spnbox/dp.c =================================================================== --- spnbox/dp.c 2009-08-19 15:49:09 UTC (rev 225) +++ spnbox/dp.c 2009-08-20 13:40:31 UTC (rev 226) @@ -7,6 +7,7 @@ #include "matrixmath.h" #include "extendedmatrix.h" #include "spnbox.h" +#include "MemoryManager.h" typedef struct dpState { @@ -44,6 +45,9 @@ from use in subnet computation.*/ int *TA; /*Active transitions.*/ int *Tuc, *Tuo; /*Uncontrollable and unobservable transitions.*/ + /*The MemoryGrower is used to reduce the number of times we'll actually have + to reallocate the index arrays above to increase their length.*/ + MemoryGrower gmem; /*Counts of the list*/ int opCount, ipCount, dpCount, apCount, upCount, cpCount, ExcludeCount, IncludeCount, TACount, TucCount, TuoCount; @@ -69,7 +73,6 @@ int uci, upd, consis; //flags matrix TSIPH; //All siphons found during a run. matrix S; //New siphons found during a run. - int ID; } dpData; /*A set of marking constraints. The return type of UpdateMarkingConstraints, @@ -85,8 +88,8 @@ more information.*/ static int CheckParams(dp_p *p); static void Sort(int* array, int length); -static void AddToArray(int** array, int length, int item); -static void AddToIndexArray(int** array, int* length, int item); +static void AddToArray(int** array, int length, int item, MemoryGrower* gmem); +static void AddToIndexArray(int** array, int* length, int item, MemoryGrower* gmem); static void UpdateDPData(dpData *data, char* description, void *newData); static MarkingConstraints UpdateMarkingConstraints(dpData *d); static dpData CreateDpData(dp_p *p); @@ -111,7 +114,7 @@ static void FinalPrint(dpData* d); static void FreeDpParts(dpData* d); -dp_r dp(dp_p* params, int ID) +dp_r dp(dp_p* params) { dp_r result; int i, j, flag; @@ -124,7 +127,7 @@ /*Initialize the data structure.*/ dpData d = CreateDpData(params); - d.ID = ID; + /*Initial message printing.*/ if (is_verbose() >= VRB_DP) { @@ -183,9 +186,8 @@ EnforceMarkingConstraints(&d); /*Build the useful places list: include all places initially.*/ - if (d.upl) free(d.upl); d.upCount = NumberOfRows(d.Dm); - d.upl = tcalloc(d.upCount, sizeof(int)); + d.upl = growCalloc(&d.gmem, d.upl, d.upCount, sizeof(int)); for (i = 0; i < d.upCount; i++) { d.upl[i] = i; @@ -272,9 +274,17 @@ /*Build the result.*/ result.Lf = d.L; - result.Bf = d.B; + if (NumberOfRows(d.L)) + { + result.Bf = tcalloc(NumberOfRows(d.L), sizeof(int)); + memcpy(result.Bf, d.B, NumberOfRows(d.L) * sizeof(int)); + } result.L0f = d.L0; - result.B0f = d.B0; + if (NumberOfRows(d.L0)) + { + result.B0f = tcalloc(NumberOfRows(d.L0), sizeof(int)); + memcpy(result.B0f, d.B0, NumberOfRows(d.L0) * sizeof(int)); + } result.how = d.status; /*Do log printing and closeout.*/ @@ -309,25 +319,14 @@ } free(d->TD); } + if (d->TDCount) free(d->TD); DeallocateMatrix(&d->Dm); DeallocateMatrix(&d->Dp); DeallocateMatrix(&d->DI); DeallocateMatrix(&d->Dcm); DeallocateMatrix(&d->Dcp); DeallocateMatrix(&d->M); - free(d->G); - free(d->opl); - free(d->ipl); - free(d->dpl); - free(d->apl); - free(d->upl); - free(d->cpl); - free(d->ExcludeT); - free(d->IncludeT); - free(d->TA); - free(d->Tuc); - free(d->Tuo); - free(d->TDCount); + FreeMemoryGrower(&d->gmem); DeallocateMatrix(&d->TSIPH); /*S may not ever have been allocated if no new siphons were found.*/ if (d->S.type) DeallocateMatrix(&d->S); @@ -679,11 +678,10 @@ int siphon, i, j, k, b, x, flag, siphons; int* currentSiphon; /*Zero the (new) control place list.*/ - free(d->cpl); - d->cpl = 0; d->cpCount = 0; siphons = NumberOfColumns(d->S); - currentSiphon = tcalloc(NumberOfRows(d->S), sizeof(int)); + MemoryGrower siphonGrower = CreateMemoryGrower(1, NumberOfRows(d->S)); + currentSiphon = growCalloc(&siphonGrower, 0, NumberOfRows(d->S), sizeof(int)); /*Iterate through each new siphon.*/ for (siphon = 0; siphon < siphons; siphon++) @@ -752,7 +750,7 @@ /*We are checking constraints for consistency, not redundancy - add the proposed new constraint to the set of constraints. Use a copy so that the memory can be absorbed into L in an optimized operation.*/ - AddToArray(&cons.B, NumberOfRows(cons.L), b); + AddToArray(&cons.B, NumberOfRows(cons.L), b, 0); AllocateMatrixType(2, &l2, 1, NumberOfColumns(l)); CopyMatrix(&l, &l2); InsertRows(&cons.L, &l2, -1, -1); @@ -793,9 +791,9 @@ if (d->log) PrintConstraints(d, &l, b, currentSiphon, NumberOfRows(d->Dm), x); /*Add the new place index to the dependent place list, the useful places list, and the new control places list.*/ - AddToIndexArray(&d->dpl, &d->dpCount, NumberOfRows(supervisRes.Dfm) - 1); - AddToIndexArray(&d->upl, &d->upCount, NumberOfRows(supervisRes.Dfm) - 1); - AddToIndexArray(&d->cpl, &d->cpCount, NumberOfRows(supervisRes.Dfm) - 1); + AddToIndexArray(&d->dpl, &d->dpCount, NumberOfRows(supervisRes.Dfm) - 1, &d->gmem); + AddToIndexArray(&d->upl, &d->upCount, NumberOfRows(supervisRes.Dfm) - 1, &d->gmem); + AddToIndexArray(&d->cpl, &d->cpCount, NumberOfRows(supervisRes.Dfm) - 1, &d->gmem); /*Dm and Dp should be set to the supervised net Dfm and Dfp.*/ UpdateDPData(d, "Dm Dp", &supervisRes); memset(&supervisRes, 0, sizeof(supervis_r)); @@ -803,23 +801,20 @@ optimized row-adds and not do too many allocations.*/ AllocateMatrixType(2, &l2, 1, NumberOfColumns(l)); CopyMatrix(&l, &l2); - AddToArray(&d->B, NumberOfRows(d->L), b); - AddToArray(&d->G, NumberOfRows(d->L), b); + AddToArray(&d->B, NumberOfRows(d->L), b, &d->gmem); + AddToArray(&d->G, NumberOfRows(d->L), b, &d->gmem); InsertRows(&d->L, &l, -1, -1); InsertRows(&d->M, &l2, -1, -1); /*Add a null row to the end of S and allocate enough space for the new siphon array.*/ InsertNullRows(&d->S, -1, 1, -1); - int *newCSiphon = tcalloc(NumberOfRows(d->S), sizeof(int)); - memcpy(newCSiphon, currentSiphon, sizeof(int) * (NumberOfRows(d->S) - 1)); - free(currentSiphon); - currentSiphon = newCSiphon; + currentSiphon = growCalloc(&siphonGrower, currentSiphon, NumberOfRows(d->S), sizeof(int)); } else { /*Add the built constraint to the initial marking constraints.*/ if (d->log) PrintConstraints(d, &l, b, currentSiphon, 0, x); - AddToArray(&d->B0, NumberOfRows(d->L0), b); + AddToArray(&d->B0, NumberOfRows(d->L0), b, &d->gmem); InsertRows(&d->L0, &l, -1, -1); } } @@ -865,7 +860,7 @@ } } DeallocateMatrix(&a); - free(currentSiphon); + FreeMemoryGrower(&siphonGrower); } /******************************************************************************* @@ -938,11 +933,11 @@ /*Update the exclusion list. It should include all transitions which are inactive. We can build this list from the active transition list already computed.*/ - free(d->ExcludeT); - d->ExcludeCount = NumberOfColumns(d->Dm) - d->TACount; + + d->ExcludeCount = NumberOfColumns(d->Dm) - d->TACount; if (d->ExcludeCount) { - d->ExcludeT = tcalloc(d->ExcludeCount, sizeof(int)); + d->ExcludeT = growCalloc(&d->gmem, d->ExcludeT, d->ExcludeCount, sizeof(int)); j = 0; k = 0; for (i = 0; i < d->TACount; i++) @@ -983,10 +978,9 @@ if (d->ipl[i] >= d->targetRows) break; } /*i now contains the number of independent places that we want to use. - Update the total count and allocate memory.*/ - free(d->upl); + Update the total count and allocate memory.*/ d->upCount = i + d->dpCount; - d->upl = tcalloc(d->upCount, sizeof(int)); + d->upl = growCalloc(&d->gmem, d->upl, d->upCount, sizeof(int)); /*Fill in the independent places.*/ for (j = 0; j < i; j++) { @@ -1054,8 +1048,9 @@ admcon_p BuildAdmconParams(dpData* d, int* siphon) { /*We'll need an updated copy of the active place list. Build it now.*/ - int *newApl = tcalloc(NumberOfRows(d->Dcm), sizeof(int)); - int newApCount = 0, i, j; + d->apl = growCalloc(&d->gmem, d->apl, NumberOfRows(d->Dcm), sizeof(int)); + int i, j; + d->apCount = 0; for (i = 0; i < NumberOfRows(d->Dcm); i++) { for (j = 0; j < NumberOfColumns(d->Dcm); j++) @@ -1065,11 +1060,8 @@ break; } } - if (j != NumberOfColumns(d->Dcm)) newApl[newApCount++] = i; + if (j != NumberOfColumns(d->Dcm)) d->apl[d->apCount++] = i; } - free(d->apl); - d->apl = newApl; - d->apCount = newApCount; /*Transform the siphon row to an admissible constraint using admcon. Start by building the admcon call parameters:*/ @@ -1144,14 +1136,15 @@ } /*Now convert the flag array to an index list. Use the same memory; this is a waste of memory but avoids an allocation.*/ - free(d->ExcludeT); + d->ExcludeCount = k; - d->ExcludeT = ExcludeFlag; + d->ExcludeT = growCalloc(&d->gmem, d->ExcludeT, d->ExcludeCount, sizeof(int)); k = 0; for (i = 0; i < NumberOfColumns(d->Dm); i++) { - if (d->ExcludeT[i]) d->ExcludeT[k++] = i; + if (ExcludeFlag[i]) d->ExcludeT[k++] = i; } + free(ExcludeFlag); } /******************************************************************************* @@ -1239,9 +1232,9 @@ /*We'll needs lists of active transitions and places. TA will have just been updated before this function call. Update apl. To avoid having to iterate - through the whole matrix twice, preallocate newApl to its maximum possible + through the whole matrix twice, preallocate apl to its maximum possible size.*/ - int *newApl = tcalloc(NumberOfRows(d->Dcm), sizeof(int)); + d->apl = growCalloc(&d->gmem, d->apl, NumberOfRows(d->Dcm), sizeof(int)); int i, j; d->apCount = 0; for (i = 0; i < NumberOfRows(d->Dcm); i++) @@ -1250,13 +1243,11 @@ { if (GetMatrixEl(&d->Dcm, i, j) || GetMatrixEl(&d->Dcp, i, j)) { - newApl[d->apCount++] = i; + d->apl[d->apCount++] = i; break; } } } - free(d->apl); - d->apl = newApl; /*Build a list of places that will be considered for siphon computation. This is any place such that it is present in both the useful and the active place @@ -1448,7 +1439,7 @@ UpdateDPData(d, "Dm Dp", &supervisRes); /*Create the dependent place list.*/ d->dpCount = NumberOfRows(d->Dm) - d->targetRows; - d->dpl = tcalloc(d->dpCount, sizeof(int)); + d->dpl = growCalloc(&d->gmem, d->dpl, d->dpCount, sizeof(int)); int i; for (i = d->targetRows; i < NumberOfRows(d->Dm); i++) { @@ -1457,7 +1448,7 @@ /*Setup M = L, G = B. Optimize for row operations.*/ AllocateMatrixType(2, &d->M, NumberOfRows(d->L), NumberOfColumns(d->L)); CopyMatrix(&d->L, &d->M); - d->G = tcalloc(NumberOfRows(d->L), sizeof(int)); + d->G = growCalloc(&d->gmem, d->G, NumberOfRows(d->L), sizeof(int)); memcpy(d->G, d->B, NumberOfRows(d->L) * sizeof(int)); } } @@ -1644,14 +1635,12 @@ } if (p->B) { - free(d->B); - d->B = tcalloc(NumberOfRows(d->L), sizeof(int)); + d->B = growCalloc(&d->gmem, d->B, NumberOfRows(d->L), sizeof(int)); memcpy(d->B, p->B, NumberOfRows(d->L) * sizeof(int)); } if (p->B0) - { - free(d->B0); - d->B0 = tcalloc(NumberOfRows(d->L0), sizeof(int)); + { + d->B0 = growCalloc(&d->gmem, d->B0, NumberOfRows(d->L0), sizeof(int)); memcpy(d->B0, p->B0, NumberOfRows(d->L0) * sizeof(int)); } } @@ -1660,12 +1649,8 @@ d->opCount = d->targetRows; d->ipCount = d->targetRows; d->dpCount = 0; - if (d->opl) free(d->opl); - if (d->ipl) free(d->ipl); - if (d->dpl) free(d->dpl); - d->opl = tcalloc(d->opCount, sizeof(int)); - d->ipl = tcalloc(d->ipCount, sizeof(int)); - d->dpl = 0; + d->opl = growCalloc(&d->gmem, d->opl, d->opCount, sizeof(int)); + d->ipl = growCalloc(&d->gmem, d->ipl, d->ipCount, sizeof(int)); int i; for (i = 0; i < d->targetRows; i++) { @@ -1674,8 +1659,6 @@ } /*Empty G and M.*/ - if (d->G) free(d->G); - d->G = 0; if (d->M.type) DeallocateMatrix(&d->M); /*Initialize M to be the right size for an msplit.*/ @@ -1732,10 +1715,12 @@ } d.targetRows = NumberOfRows(p->Dm); d.targetCols = NumberOfColumns(p->Dm); + /*Initialize the memory grower that will be used with the index lists.*/ + d.gmem = CreateMemoryGrower(15, d.targetRows > d.targetCols ? d.targetRows : d.targetCols); /*Copy index lists (and fill in the corresponding flags).*/ if (p->Tuc && p->TucCount) { - d.Tuc = tcalloc(p->TucCount, sizeof(int)); + d.Tuc = growCalloc(&d.gmem, 0, p->TucCount, sizeof(int)); d.TucCount = p->TucCount; memcpy(d.Tuc, p->Tuc, sizeof(int) * p->TucCount); /*Make sure the index array is sorted. This will allow us to speed up @@ -1744,7 +1729,7 @@ } if (p->Tuo && p->TuoCount) { - d.Tuo = tcalloc(p->TuoCount, sizeof(int)); + d.Tuo = growCalloc(&d.gmem, 0, p->TuoCount, sizeof(int)); d.TuoCount = p->TuoCount; memcpy(d.Tuo, p->Tuo, sizeof(int) * p->TuoCount); /*Make sure the index array is sorted. This will allow us to speed up @@ -1753,7 +1738,7 @@ } if (p->ExcludeT && p->ExcludeCount) { - d.ExcludeT = tcalloc(p->ExcludeCount, sizeof(int)); + d.ExcludeT = growCalloc(&d.gmem, 0, p->ExcludeCount, sizeof(int)); d.ExcludeCount = p->ExcludeCount; memcpy(d.ExcludeT, p->ExcludeT, sizeof(int) * p->ExcludeCount); /*Make sure the index array is sorted. This will allow us to speed up @@ -1762,7 +1747,7 @@ } if (p->IncludeT && p->IncludeCount) { - d.IncludeT = tcalloc(p->IncludeCount, sizeof(int)); + d.IncludeT = growCalloc(&d.gmem, 0, p->IncludeCount, sizeof(int)); d.IncludeCount = p->IncludeCount; memcpy(d.IncludeT, p->IncludeT, sizeof(int) * p->IncludeCount); /*Make sure the index array is sorted. This will allow us to speed up @@ -1772,7 +1757,7 @@ else { /*If IncludeT is not present, it defaults to including all transitions.*/ - d.IncludeT = tcalloc(d.targetCols, sizeof(int)); + d.IncludeT = growCalloc(&d.gmem, 0, d.targetCols, sizeof(int)); d.IncludeCount = d.targetCols; for (i = 0; i < d.targetCols; i++) { @@ -1781,13 +1766,13 @@ } /*Copy the constraint vectors*/ if (p->B) - { - d.B = tcalloc(NumberOfRows(d.L), sizeof(int)); + { + d.B = growCalloc(&d.gmem, 0, NumberOfRows(d.L), sizeof(int)); memcpy(d.B, p->B, NumberOfRows(d.L) * sizeof(int)); } if (p->B0) { - d.B0 = tcalloc(NumberOfRows(d.L0), sizeof(int)); + d.B0 = growCalloc(&d.gmem, 0, NumberOfRows(d.L0), sizeof(int)); memcpy(d.B0, p->B0, NumberOfRows(d.L0) * sizeof(int)); } /*The only one of the state flags that does not default to zero is perm.*/ @@ -1871,7 +1856,7 @@ } if (count && (d->B || d->B0)) { - result.B = tcalloc(count, sizeof(int)); + result.B = calloc(count, sizeof(int)); if (d->B) { memcpy(result.B, d->B, sizeof(int) * NumberOfRows(d->L)); @@ -1913,6 +1898,9 @@ matrix* destMatrix = 0; int* destInt = 0; int** destIntArray = 0; + int** destGrownArray = 0; + int destGrownArrayCapacity = -1; + int* destGrownArrayCount = 0; int*** destTD = 0; /*If we encounter an ignore instruction, we want to ignore the next paramater. If we encounter a deallocate instruction, we want to deallocate @@ -1965,19 +1953,31 @@ merror(0, "DP: Internal Error: 'matrix' encounted without a 'free' or 'ignore' directive"); } } - else if (! strcmp(token, "B")) destIntArray = &data->B; - else if (! strcmp(token, "B0")) destIntArray = &data->B0; - else if (! strcmp(token, "G")) destIntArray = &data->G; - else if (! strcmp(token, "opl")) destIntArray = &data->opl; - else if (! strcmp(token, "ipl")) destIntArray = &data->ipl; - else if (! strcmp(token, "dpl")) destIntArray = &data->dpl; - else if (! strcmp(token, "apl")) destIntArray = &data->apl; - else if (! strcmp(token, "ExcludeT")) destIntArray = &data->ExcludeT; - else if (! strcmp(token, "IncludeT")) destIntArray = &data->IncludeT; - else if (! strcmp(token, "TA")) destIntArray = &data->TA; - else if (! strcmp(token, "Tuc")) destIntArray = &data->Tuc; - else if (! strcmp(token, "Tuo")) destIntArray = &data->Tuo; - else if (! strcmp(token, "upl")) destIntArray = &data->upl; + else if (! strcmp(token, "B")) + { + destGrownArray = &data->B; + destGrownArrayCapacity = NumberOfRows(data->L); + } + else if (! strcmp(token, "B0")) + { + destGrownArray = &data->B0; + destGrownArrayCapacity = NumberOfRows(data->L0); + } + else if (! strcmp(token, "G")) + { + destGrownArray = &data->G; + destGrownArrayCapacity = NumberOfRows(data->L); + } + else if (! strcmp(token, "opl")) destGrownArray = &data->opl; + else if (! strcmp(token, "ipl")) destGrownArray = &data->ipl; + else if (! strcmp(token, "dpl")) destGrownArray = &data->dpl; + else if (! strcmp(token, "apl")) destGrownArray = &data->apl; + else if (! strcmp(token, "ExcludeT")) destGrownArray = &data->ExcludeT; + else if (! strcmp(token, "IncludeT")) destGrownArray = &data->IncludeT; + else if (! strcmp(token, "TA")) destGrownArray = &data->TA; + else if (! strcmp(token, "Tuc")) destGrownArray = &data->Tuc; + else if (! strcmp(token, "Tuo")) destGrownArray = &data->Tuo; + else if (! strcmp(token, "upl")) destGrownArray = &data->upl; else if (! strcmp(token, "intarray")) { if (ignore) destIntArray = (int**) 1; @@ -2005,6 +2005,34 @@ merror(0, "DP: Internal Error"); return; } + if (destGrownArray) + { + if (ignore || deallocate) + { + destIntArray = destGrownArray; + } + else + { + /*If we have not been given the new capacity via some other function, + it is the next value in the given values. Peek ahead to get it.*/ + if (destGrownArrayCapacity < 0) + { + destIntArray = next; + destInt = (int*)(++destIntArray); + destGrownArrayCapacity = *destInt; + destIntArray = 0; + destInt = 0; + } + /*Grow the array to the required capacity.*/ + (*destGrownArray) = growCalloc(&data->gmem, *destGrownArray, destGrownArrayCapacity, sizeof(int)); + /*Copy the previous array to the new one.*/ + memcpy(*destGrownArray, *((int**)next), destGrownArrayCapacity * sizeof(int)); + free(*((int**)next)); + /*Shift the next pointer as appropriate.*/ + destGrownArray = next; + next = ++destGrownArray; + } + } if (destMatrix) { if ((! ignore) && destMatrix->type) DeallocateMatrix(destMatrix); @@ -2047,25 +2075,39 @@ This function adds an item to an index array, increments the count, and makes sure the array is sorted properly. Note the Sort will make at only one pass through an array that is already properly sorted, so this is low-cost.*/ -void AddToIndexArray(int** array, int* length, int item) +void AddToIndexArray(int** array, int* length, int item, MemoryGrower* gmem) { - int *newArray = tcalloc(*length + 1, sizeof(int)); - if (length) memcpy(newArray, *array, sizeof(int) * (*length)); - newArray[(*length)++] = item; - free(*array); - *array = newArray; + if (gmem) + { + *array = growCalloc(gmem, *array, *length + 1, sizeof(int)); + } + else + { + int *newArray = tcalloc(*length + 1, sizeof(int)); + if (length) memcpy(newArray, *array, sizeof(int) * (*length)); + free(*array); + *array = newArray; + } + (*array)[(*length)++] = item; Sort(*array, *length); } /******************************************************************************* This function adds an item to an integer array.*/ -void AddToArray(int** array, int length, int item) +void AddToArray(int** array, int length, int item, MemoryGrower* gmem) { - int* newArray = tcalloc(length + 1, sizeof(int)); - if (length) memcpy(newArray, *array, sizeof(int) * length); - newArray[length] = item; - free(*array); - *array = newArray; + if (gmem) + { + *array = growCalloc(gmem, *array, length + 1, sizeof(int)); + } + else + { + int* newArray = tcalloc(length + 1, sizeof(int)); + if (length) memcpy(newArray, *array, sizeof(int) * length); + free(*array); + *array = newArray; + } + (*array)[length] = item; } /******************************************************************************* Modified: spnbox/dp4.c =================================================================== --- spnbox/dp4.c 2009-08-19 15:49:09 UTC (rev 225) +++ spnbox/dp4.c 2009-08-20 13:40:31 UTC (rev 226) @@ -63,7 +63,6 @@ int uci, upd, consis; //flags matrix TSIPH; //All siphons found during a run. matrix S; //New siphons found during a run. - int ID; } dpData; /*A set of marking constraints. The return type of UpdateMarkingConstraints, @@ -105,7 +104,7 @@ static void FinalPrint(dpData* d); static void FreeDpParts(dpData* d); -dp_r dp(dp_p* params, int ID) +dp_r dp(dp_p* params) { dp_r result; int i, j, flag; @@ -118,7 +117,6 @@ /*Initialize the data structure.*/ dpData d = CreateDpData(params); - d.ID = ID; /*Initial message printing.*/ if (is_verbose() >= VRB_DP) { Modified: spnbox/invar.c =================================================================== --- spnbox/invar.c 2009-08-19 15:49:09 UTC (rev 225) +++ spnbox/invar.c 2009-08-20 13:40:31 UTC (rev 226) @@ -29,9 +29,9 @@ routine set in MemoryManager.c)*/ d.gmem = CreateMemoryGrower(3, NumberOfRows(d.B) * sizeof(int)); int i, j, flag; - d.Ip = GetGrowableMemory(&d.gmem, NumberOfRows(d.B) * sizeof(int)); - d.Im = GetGrowableMemory(&d.gmem, NumberOfRows(d.B) * sizeof(int)); - d.I = GetGrowableMemory(&d.gmem, NumberOfRows(d.B) * sizeof(int)); + d.Ip = growCalloc(&d.gmem, 0, NumberOfRows(d.B), sizeof(int)); + d.Im = growCalloc(&d.gmem, 0, NumberOfRows(d.B), sizeof(int)); + d.I = growCalloc(&d.gmem, 0, NumberOfRows(d.B), sizeof(int)); /*Iterate through columns of B.*/ for (j = 0; j < NumberOfColumns(d.B); j++) @@ -84,9 +84,9 @@ } /*Make sure I, Ip, and Im are as large as they need to be for the next loop iteration.*/ - d.I = GrowMemory(&d.gmem, d.I, sizeof(int) * NumberOfRows(d.C)); - d.Ip = GrowMemory(&d.gmem, d.Ip, sizeof(int) * NumberOfRows(d.C)); - d.Im = GrowMemory(&d.gmem, d.Im, sizeof(int) * NumberOfRows(d.C)); + d.I = growCalloc(&d.gmem, d.I, sizeof(int), NumberOfRows(d.C)); + d.Ip = growCalloc(&d.gmem, d.Ip, sizeof(int), NumberOfRows(d.C)); + d.Im = growCalloc(&d.gmem, d.Im, sizeof(int), NumberOfRows(d.C)); if (! NumberOfRows(d.B)) break; } } @@ -150,7 +150,7 @@ { int i, j, k, less, more; /*Make sure I is big enough to hold all the new flags.*/ - d->I = GrowMemory(&d->gmem, d->I, sizeof(int) * NumberOfRows(d->C)); + d->I = growCalloc(&d->gmem, d->I, sizeof(int), NumberOfRows(d->C)); /*Clear I.*/ memset(d->I, 0, sizeof(int) * NumberOfRows(d->C)); for (i = 0; i < NumberOfRows(d->C); i++) @@ -225,7 +225,7 @@ SetMatrixEl(&d->C, NumberOfRows(d->C) - 1, l, c); } /*Flag the new row in I.*/ - d->I = GrowMemory(&d->gmem, d->I, sizeof(int) * NumberOfRows(d->C)); + d->I = growCalloc(&d->gmem, d->I, sizeof(int), NumberOfRows(d->C)); d->I[NumberOfRows(d->C) - 1] = 1; } } Modified: spnbox/spnbox.h =================================================================== --- spnbox/spnbox.h 2009-08-19 15:49:09 UTC (rev 225) +++ spnbox/spnbox.h 2009-08-20 13:40:31 UTC (rev 226) @@ -1031,7 +1031,7 @@ int option; } dp_p; -dp_r dp(dp_p* params, int ID); +dp_r dp(dp_p* params); /* Matlab Usage: Modified: spnbox/tests/Makefile =================================================================== --- spnbox/tests/Makefile 2009-08-19 15:49:09 UTC (rev 225) +++ spnbox/tests/Makefile 2009-08-20 13:40:31 UTC (rev 226) @@ -6,7 +6,7 @@ #This variable controls whether or not the memwatch memory debugging routines are included in #compilation. Set to "yes" to include them and "no" to leave them out. -USEMEMWATCH = no +USEMEMWATCH = yes #Assign the default compiler call and options. COMPILER=gcc -g @@ -55,7 +55,7 @@ COMMONHEADER=../spnbox.h test.h ../../pnheaders/general.h ../../pnheaders/pns.h ../../pnheaders/matrix.h ../matrixmath.h ../MemoryManager.h StructuredIO.h #Targets -all: avpr extendedmatrix fvpr gcdv invar ipslv ipsolve isadm issiph msplit matrixmath pn2acpn supervis actn admcon asiph ilpadm linenf nltrans pn2eacpn reduce tactn +all: avpr dp dp4 extendedmatrix fvpr gcdv invar ipslv ipsolve isadm issiph msplit matrixmath pn2acpn supervis actn admcon asiph ilpadm linenf nltrans pn2eacpn reduce tactn avpr: test-avpr.o $(AVPR) $(COMMON) $(COMPILER) -o avpr.exe test-avpr.o $(AVPR) $(COMMON) extendedmatrix: test-extendedmatrix.o $(EXTENDEDMATRIX) $(COMMON) Modified: spnbox/tests/test-dp.c =================================================================== --- spnbox/tests/test-dp.c 2009-08-19 15:49:09 UTC (rev 225) +++ spnbox/tests/test-dp.c 2009-08-20 13:40:31 UTC (rev 226) @@ -7,11 +7,11 @@ { return 0; } - char iDesc[] = "matrix D, matrix Dm, matrix Dp, indexarray Tuc, indexarray Tuo, arrayi IncludeT, arrayi ExcludeT, arrayi B, arrayi B0, matrix L, matrix L0, string WriteLog, string EnforceLive, int ID"; + char iDesc[] = "matrix D, matrix Dm, matrix Dp, indexarray Tuc, indexarray Tuo, arrayi IncludeT, arrayi ExcludeT, arrayi B, arrayi B0, matrix L, matrix L0, string WriteLog, string EnforceLive"; char oDesc[] = "matrix Lf, arrayi Bf, matrix L0f, arrayi B0f, string how"; int *iFill; int oFill[5]; - int BCount, B0Count, i, ID; + int BCount, B0Count, i; matrix D; char WriteLog[128] = "", EnforceLive[128] = ""; dp_p p; @@ -30,11 +30,11 @@ remove("dp.log"); remove("dp.dat"); int transitions; - ID = -1; - while (ParseStructure(input, iDesc, &iFill, &mem, &D, &p.Dm, &p.Dp, &p.Tuc, &p.TucCount, &p.Tuo, &p.TuoCount, &p.IncludeT, &p.IncludeCount, &p.ExcludeT, &p.ExcludeCount, &p.B, &BCount, &p.B0, &B0Count, &p.L, &p.L0, WriteLog, EnforceLive, &ID)) + + while (ParseStructure(input, iDesc, &iFill, &mem, &D, &p.Dm, &p.Dp, &p.Tuc, &p.TucCount, &p.Tuo, &p.TuoCount, &p.IncludeT, &p.IncludeCount, &p.ExcludeT, &p.ExcludeCount, &p.B, &BCount, &p.B0, &B0Count, &p.L, &p.L0, WriteLog, EnforceLive)) { transitions = (iFill[0] ? NumberOfColumns(D) : (iFill[1] ? NumberOfColumns(p.Dm) : (iFill[2] ? NumberOfColumns(p.Dp) : 0))); - DisplayStructure(iDesc, iFill, &D, &p.Dm, &p.Dp, p.Tuc, p.TucCount, NumberOfColumns(p.Dm), p.Tuo, p.TuoCount, NumberOfColumns(p.Dm), p.IncludeT, p.IncludeCount, p.ExcludeT, p.ExcludeCount, p.B, BCount, p.B0, B0Count, &p.L, &p.L0, WriteLog, EnforceLive, ID); + DisplayStructure(iDesc, iFill, &D, &p.Dm, &p.Dp, p.Tuc, p.TucCount, NumberOfColumns(p.Dm), p.Tuo, p.TuoCount, NumberOfColumns(p.Dm), p.IncludeT, p.IncludeCount, p.ExcludeT, p.ExcludeCount, p.B, BCount, p.B0, B0Count, &p.L, &p.L0, WriteLog, EnforceLive); FillDmDp(iFill, &D, &p.Dm, &p.Dp, &mem); /*Log writing defaults to on.*/ if (strcmp(WriteLog, "off")) p.option |= DP_OPT_WRITELOG; @@ -54,7 +54,7 @@ //For the duration of a test, append to the log files. p.option |= DP_OPT_APPENDLOGS; - dp_r res = dp(&p, ID); + dp_r res = dp(&p); printf("Solution:\n"); DisplayStructure(oDesc, oFill, &res.Lf, res.Bf, NumberOfRows(res.Lf), &res.L0f, res.B0f, NumberOfRows(res.L0f), res.how); printf("-------------------------------------------------------------------------------\n\n"); @@ -63,7 +63,6 @@ mem = CreateMemoryManager(10, 10, 0, 0); memset(&p, 0, sizeof(dp_p)); - ID = -1; WriteLog[0] = '\0'; EnforceLive[0] = '\0'; } Modified: spnbox/tests/test-dp.txt =================================================================== --- spnbox/tests/test-dp.txt 2009-08-19 15:49:09 UTC (rev 225) +++ spnbox/tests/test-dp.txt 2009-08-20 13:40:31 UTC (rev 226) @@ -11,7 +11,6 @@ echo Answer should be: echo L = [ 2 2 1 ] echo b = [ 2 ] -ID 1 Dp 3 5 0 1 0 1 0 0 0 1 0 1 @@ -25,7 +24,6 @@ echo Problem 2. echo A Petri net in which deadlock cannot be prevented. -ID 2 Dp 3 3 0 1 0 0 0 1 @@ -39,7 +37,6 @@ echo Problem 3. echo A repetetive Petri net with no smaller siphons. -ID 3 Dm 3 3 0 1 0 1 0 0 @@ -54,7 +51,6 @@ echo Problem 4. echo A similar net that is not strongly connected, i.e. the union of two echo distinct repetitive Petri nets. -ID 4 Dm 6 6 0 1 0 0 0 0 1 0 0 0 0 0 @@ -81,7 +77,6 @@ echo B = [ 1 ] echo ....[ 1 ] echo ....[ 3 ] -ID 5 Dm 4 5 1 0 1 0 1 0 0 0 1 0 @@ -101,7 +96,6 @@ echo L = [ 1 1 0 0 ] B = [ 1 ] echo ....[ 0 0 1 1 ] [ 1 ] echo ....[ 1 1 1 1 ] [ 3 ] -ID 6 Dm 4 5 1 0 1 0 1 0 0 0 1 0 @@ -124,7 +118,6 @@ echo This is an example from K. Lautenback, et al, "The Linear Algebra of echo Deadlock Avoidance - A Petri Net Approach", technical report at the echo University of Koblenz, Institute for Computer Science, 1996. -ID 7 Dm 4 4 3 0 5 0 0 1 0 0 @@ -143,7 +136,6 @@ echo L = [ 2 0 1 ] B = [ 1 ] echo .....[ 0 2 1 ] [ 1 ] echo L0 = [ 2 2 2 ] B0 = [ 3 ] -ID 8 D 3 3 -1 1 0 -1 0 1 @@ -156,7 +148,6 @@ echo ----- Liveness Enforcement Tests ----- echo --------------------------------------------------------------------------- echo Problem 0. (from dpdem4.m) -ID 100 D 15 11 -1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 -1 0 0 0 0 @@ -179,7 +170,6 @@ echo Problem 1. Example 5.2 from the ISIS report #4 of 2000. echo The answer should be: echo L = [ 2 2 1 ] B = [ 2 ] -ID 101 Dp 3 5 0 1 0 1 0 0 0 1 0 1 @@ -192,7 +182,6 @@ done echo Problem 2. A Petri net in which deadlock cannot be prevented. -ID 102 Dp 3 3 0 1 0 0 0 1 @@ -205,7 +194,6 @@ done echo Problem 3. A repetitive net. -ID 103 Dm 3 3 0 1 0 1 0 0 @@ -218,7 +206,6 @@ done echo Problem 4. The union of two distinct repetetive Petri nets. -ID 104 Dm 6 6 0 1 0 0 0 0 1 0 0 0 0 0 @@ -237,7 +224,6 @@ done echo Problem 5. DAta from Example 5.1 from ISIS report #3 of 2000. -ID 105 Dm 4 5 1 0 1 0 1 0 0 0 1 0 @@ -253,7 +239,6 @@ echo Problem 6. The same as Problem 5 (Data from Example 5.1 from ISIS report #3 echo of 2000.) except with an initial constraint. -ID 106 Dm 4 5 1 0 1 0 1 0 0 0 1 0 @@ -276,7 +261,6 @@ echo L = [ 2 0 1 ] B = [ 1 ] echo .....[ 0 2 1 ] [ 1 ] echo L0 = [ 2 2 2 ] B0 = [ 3 ] -ID 107 D 3 3 -1 1 0 -1 0 1 @@ -291,7 +275,6 @@ echo L = [ 1 0 1 1 1 ] B = [ 1 ] echo .....[ 0 1 1 1 1 ] [ 1 ] echo L0 = [ -1 -1 -1 -1 -1 ] B0 = [ -1 ] -ID 108 D 5 6 -1 1 0 0 0 0 -1 0 1 0 0 0 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |