Skip to content

Commit 328af92

Browse files
author
Max
committed
Fix incorrect segment unloading, fix free memory search
1 parent 9f92faf commit 328af92

1 file changed

Lines changed: 39 additions & 25 deletions

File tree

mmemory.c

Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -151,10 +151,10 @@ Segment* initialize_free_segment(PA pAddress, size_t nSize, Segment* pPrevious,
151151
}
152152

153153
LOG("Free memory segment initialized:");
154-
LOG_LONG("\tsize:", nSize);
154+
LOG_LONG("\tsize:", pFreeSegment->nSize);
155155
LOG_ADDR("\taddress:", LONG(pFreeSegment));
156156
LOG_ADDR("\tnext:", LONG(pFreeSegment->pNext));
157-
LOG_ADDR("\tprev:", LONG(pFreeSegment->pPrev));
157+
LOG_ADDR("\tprev:", LONG(pFreeSegment->pPrev));
158158

159159
return pFreeSegment;
160160
}
@@ -186,9 +186,9 @@ Segment* unload_segment(SegmentRecord* pRecord)
186186

187187
// update record state
188188
pRecord->pSegAddress = pDiskMemory;
189-
pRecord->bIsPresent = false;
190-
pSegmentToUnload->pPrev = NULL;
191-
pSegmentToUnload->pNext = NULL;
189+
pRecord->bIsPresent = false;
190+
pRecord->segment.pPrev = NULL;
191+
pRecord->segment.pNext = NULL;
192192

193193
LOG("Segment successfully unloaded");
194194

@@ -213,7 +213,7 @@ Segment* find_free_place_for_segment(size_t nSize, bool bForce)
213213
// + sizeof(Segment) - ensure that there will be no free segments with size < sizeof(Segment)
214214
const size_t nSizeWithOffset = nSize + sizeof(Segment);
215215

216-
Segment* pSeg = g_pSegTable->pSegListHead;
216+
Segment* pSeg = g_pSegTable->pSegListHead;
217217
while (pSeg)
218218
{
219219
LOG(" found segment:");
@@ -243,13 +243,12 @@ Segment* find_free_place_for_segment(size_t nSize, bool bForce)
243243
break;
244244
pSeg = pSeg->pNext;
245245
}
246-
assert(pSeg);
247246

248247
// find largest segment
249248
Segment* pLargestSegment = pSeg;
250249
while (pSeg)
251250
{
252-
if (!pSeg->bIsFree)
251+
if (!pSeg->bIsFree && !segment_is_forbidden(RECORD(pSeg)))
253252
{
254253
// found segment with suitable size
255254
if (pSeg->nSize >= nSizeWithOffset || pSeg->nSize == nSize)
@@ -263,6 +262,12 @@ Segment* find_free_place_for_segment(size_t nSize, bool bForce)
263262
}
264263

265264
// unload largest segment found
265+
if (!pSeg)
266+
{
267+
LOG("Cannot deallocate enough memory for segment");
268+
return NULL;
269+
}
270+
266271
LOG_ADDR("Unloading largest:", LONG(pLargestSegment));
267272
Segment* pFreeSeg = unload_segment(RECORD(pLargestSegment));
268273

@@ -335,7 +340,7 @@ bool load_segment_into_memory(SegmentRecord* pRecord, Segment* pFreeSegment)
335340
}
336341

337342
// link previous segment to the new one
338-
pSegmentToLoad->pPrev = pFreeSegment->pPrev;
343+
pSegmentToLoad->pPrev = pFreeSegment->pPrev;
339344
if (pFreeSegment->pPrev)
340345
pFreeSegment->pPrev->pNext = pSegmentToLoad;
341346
else
@@ -353,7 +358,7 @@ bool load_segment_into_memory(SegmentRecord* pRecord, Segment* pFreeSegment)
353358
pRecord->pSegAddress = (PA)pFreeSegment;
354359
pRecord->bIsPresent = true;
355360
//pSegmentToLoad->bIsFree = false;
356-
361+
357362
LOG("Segment has been successfully loaded");
358363
return true;
359364
}
@@ -605,10 +610,7 @@ int m_free(VA ptr)
605610
SegmentRecord* pRecord = GET_SEG_RECORD_NO(nSegmentIndex);
606611

607612
// TODO: ignore non-zero offset?
608-
if (nSegmentIndex >= g_pSegTable->nSize ||
609-
nSegmentIndex < 0 ||
610-
pRecord->bIsAvailable ||
611-
nSegmentOffset != 0)
613+
if (pRecord->bIsAvailable || nSegmentOffset != 0)
612614
{
613615
LOG("m_free: ERROR! Wrong parameters");
614616
return WRONG_PARAMETERS;
@@ -623,7 +625,7 @@ int m_free(VA ptr)
623625
}
624626
else
625627
{
626-
LOG("Deallocating disk memory");
628+
LOG_ADDR("Deallocating disk memory at:", LONG(pRecord->pSegAddress));
627629
free(pRecord->pSegAddress);
628630
}
629631

@@ -686,20 +688,25 @@ int m_write(VA ptr, void* pBuffer, size_t szBuffer)
686688
LOG_INT(" segment no.", nSegmentIndex);
687689
LOG_INT(" offset:", nSegmentOffset);
688690

689-
if (nSegmentIndex >= g_pSegTable->nSize || nSegmentIndex < 0)
690-
return WRONG_PARAMETERS;
691+
if (nSegmentIndex >= g_pSegTable->nSize || nSegmentIndex < 0)
692+
{
693+
LOG("m_write: ERROR! Wrong segment index");
694+
return WRONG_PARAMETERS;
695+
}
691696

692697
SegmentRecord* pRecord = GET_SEG_RECORD_NO(nSegmentIndex);
693698

694-
if (nSegmentOffset >= pRecord->segment.nSize ||
695-
nSegmentOffset < 0 ||
696-
pRecord->bIsAvailable ||
697-
!pBuffer ||
698-
szBuffer <= 0)
699-
return WRONG_PARAMETERS;
699+
if (pRecord->bIsAvailable || !pBuffer || szBuffer <= 0)
700+
{
701+
LOG("m_write: ERROR! Wrong parameters");
702+
return WRONG_PARAMETERS;
703+
}
700704

701-
if ((pRecord->segment.nSize - nSegmentOffset) < szBuffer)
702-
return SEGMENT_VIOLATION;
705+
if ((pRecord->segment.nSize - nSegmentOffset) < szBuffer)
706+
{
707+
LOG("m_write: ERROR! Writing outside the segment");
708+
return SEGMENT_VIOLATION;
709+
}
703710

704711
// TODO: check size
705712
if (!pRecord->bIsPresent)
@@ -709,6 +716,12 @@ int m_write(VA ptr, void* pBuffer, size_t szBuffer)
709716
load_adjacent_segments_into_memory(nSegmentIndex);
710717
}
711718

719+
if (!pRecord->bIsPresent)
720+
{
721+
LOG("m_write: ERROR! Can not load required segment into memory");
722+
return UNKNOWN_ERROR;
723+
}
724+
712725
LOG_INT("Writing into segment from buffer of size:", szBuffer);
713726
memcpy(VOID(pRecord->pSegAddress + nSegmentOffset), pBuffer, szBuffer);
714727

@@ -741,6 +754,7 @@ int m_init(int n, int szPage)
741754

742755
const long nTotalMemory = LONG(n) * szPage;
743756
const int nTableInitialSize = SEG_TABLE_SIZE(SEG_TABLE_INCREMENT);
757+
g_nCurrentVasSize = 0;
744758

745759
// limit min size of allocated memory
746760
if (nTotalMemory < nTableInitialSize + MIN_SEG_SIZE)

0 commit comments

Comments
 (0)