|
@@ -190,9 +190,9 @@ const
|
|
{$endif}
|
|
{$endif}
|
|
|
|
|
|
var
|
|
var
|
|
- main_relo_freelists : pfreelists;
|
|
|
|
orphaned_freelists : tfreelists;
|
|
orphaned_freelists : tfreelists;
|
|
heap_lock : trtlcriticalsection;
|
|
heap_lock : trtlcriticalsection;
|
|
|
|
+ heap_lock_use : integer;
|
|
threadvar
|
|
threadvar
|
|
freelists : tfreelists;
|
|
freelists : tfreelists;
|
|
|
|
|
|
@@ -1392,6 +1392,12 @@ procedure InitHeapThread;
|
|
var
|
|
var
|
|
loc_freelists: pfreelists;
|
|
loc_freelists: pfreelists;
|
|
begin
|
|
begin
|
|
|
|
+ if heap_lock_use > 0 then
|
|
|
|
+ begin
|
|
|
|
+ entercriticalsection(heap_lock);
|
|
|
|
+ inc(heap_lock_use);
|
|
|
|
+ leavecriticalsection(heap_lock);
|
|
|
|
+ end;
|
|
loc_freelists := @freelists;
|
|
loc_freelists := @freelists;
|
|
fillchar(loc_freelists^,sizeof(tfreelists),0);
|
|
fillchar(loc_freelists^,sizeof(tfreelists),0);
|
|
{$ifdef DUMP_MEM_USAGE}
|
|
{$ifdef DUMP_MEM_USAGE}
|
|
@@ -1406,6 +1412,7 @@ var
|
|
begin
|
|
begin
|
|
{ we cannot initialize the locks here yet, thread support is
|
|
{ we cannot initialize the locks here yet, thread support is
|
|
not loaded yet }
|
|
not loaded yet }
|
|
|
|
+ heap_lock_use := 0;
|
|
loc_freelists := @freelists;
|
|
loc_freelists := @freelists;
|
|
fillchar(loc_freelists^,sizeof(tfreelists),0);
|
|
fillchar(loc_freelists^,sizeof(tfreelists),0);
|
|
fillchar(orphaned_freelists,sizeof(orphaned_freelists),0);
|
|
fillchar(orphaned_freelists,sizeof(orphaned_freelists),0);
|
|
@@ -1417,9 +1424,12 @@ var
|
|
begin
|
|
begin
|
|
{ this function should be called in main thread context }
|
|
{ this function should be called in main thread context }
|
|
loc_freelists := @freelists;
|
|
loc_freelists := @freelists;
|
|
- main_relo_freelists := loc_freelists;
|
|
|
|
|
|
+ heap_lock_use := 1;
|
|
initcriticalsection(heap_lock);
|
|
initcriticalsection(heap_lock);
|
|
- modify_freelists(loc_freelists, main_relo_freelists);
|
|
|
|
|
|
+ { loc_freelists still points to main thread's freelists, but they
|
|
|
|
+ have a reference to the global main freelists, fix them to point
|
|
|
|
+ to the main thread specific variable }
|
|
|
|
+ modify_freelists(loc_freelists, loc_freelists);
|
|
if MemoryManager.RelocateHeap <> nil then
|
|
if MemoryManager.RelocateHeap <> nil then
|
|
MemoryManager.RelocateHeap();
|
|
MemoryManager.RelocateHeap();
|
|
end;
|
|
end;
|
|
@@ -1428,12 +1438,13 @@ procedure FinalizeHeap;
|
|
var
|
|
var
|
|
poc, poc_next: poschunk;
|
|
poc, poc_next: poschunk;
|
|
loc_freelists: pfreelists;
|
|
loc_freelists: pfreelists;
|
|
|
|
+ last_thread: boolean;
|
|
{$ifdef DUMP_MEM_USAGE}
|
|
{$ifdef DUMP_MEM_USAGE}
|
|
i : longint;
|
|
i : longint;
|
|
{$endif}
|
|
{$endif}
|
|
begin
|
|
begin
|
|
loc_freelists := @freelists;
|
|
loc_freelists := @freelists;
|
|
- if main_relo_freelists <> nil then
|
|
|
|
|
|
+ if heap_lock_use > 0 then
|
|
begin
|
|
begin
|
|
entercriticalsection(heap_lock);
|
|
entercriticalsection(heap_lock);
|
|
finish_waitfixedlist(loc_freelists);
|
|
finish_waitfixedlist(loc_freelists);
|
|
@@ -1453,22 +1464,21 @@ begin
|
|
end;
|
|
end;
|
|
loc_freelists^.oslist := nil;
|
|
loc_freelists^.oslist := nil;
|
|
loc_freelists^.oscount := 0;
|
|
loc_freelists^.oscount := 0;
|
|
- if main_relo_freelists <> nil then
|
|
|
|
|
|
+ if heap_lock_use > 0 then
|
|
begin
|
|
begin
|
|
{$endif HAS_SYSOSFREE}
|
|
{$endif HAS_SYSOSFREE}
|
|
- if main_relo_freelists <> loc_freelists then
|
|
|
|
|
|
+ poc := modify_freelists(loc_freelists, @orphaned_freelists);
|
|
|
|
+ if assigned(poc) then
|
|
begin
|
|
begin
|
|
- poc := modify_freelists(loc_freelists, @orphaned_freelists);
|
|
|
|
- if assigned(poc) then
|
|
|
|
- begin
|
|
|
|
- poc^.next_any := orphaned_freelists.oslist_all;
|
|
|
|
- if assigned(orphaned_freelists.oslist_all) then
|
|
|
|
- orphaned_freelists.oslist_all^.prev_any := poc;
|
|
|
|
- orphaned_freelists.oslist_all := loc_freelists^.oslist_all;
|
|
|
|
- end;
|
|
|
|
|
|
+ poc^.next_any := orphaned_freelists.oslist_all;
|
|
|
|
+ if assigned(orphaned_freelists.oslist_all) then
|
|
|
|
+ orphaned_freelists.oslist_all^.prev_any := poc;
|
|
|
|
+ orphaned_freelists.oslist_all := loc_freelists^.oslist_all;
|
|
end;
|
|
end;
|
|
|
|
+ dec(heap_lock_use);
|
|
|
|
+ last_thread := heap_lock_use = 0;
|
|
leavecriticalsection(heap_lock);
|
|
leavecriticalsection(heap_lock);
|
|
- if main_relo_freelists = loc_freelists then
|
|
|
|
|
|
+ if last_thread then
|
|
donecriticalsection(heap_lock);
|
|
donecriticalsection(heap_lock);
|
|
end;
|
|
end;
|
|
{$ifdef SHOW_MEM_USAGE}
|
|
{$ifdef SHOW_MEM_USAGE}
|