# $SectionObjectPointer{$SectionObjectPointer}{"SharedCacheMap"}="0x12345678";
# $SharedCacheMap{$SharedCacheMap}{"SharedCacheMap"}="0x12345678";
# $SharedCacheMap{$SharedCacheMap}{"SectionObjectPointer"}="0x12345678";
-# $SharedCacheMap{$SharedCacheMap}{"Allocation"}="0x12345";
+# $SharedCacheMap{$SharedCacheMap}{"AllocationSize"}="0x12345";
# $SharedCacheMap{$SharedCacheMap}{"FileSize"}="0x12345";
# $SharedCacheMap{$SharedCacheMap}{"ref_count"}=1;
# $SharedCacheMap{$SharedCacheMap}{"map"}="0x12345678" (Bcb);
# $SharedCacheMap{$SharedCacheMap}{"PinAccess"}=0 or 1;
# $SharedCacheMap{$SharedCacheMap}{"LogHandle"}="0x12345678" optional;
# $SharedCacheMap{$SharedCacheMap}{"AcquireForLazyWrite"}=0; # count
+# $SharedCacheMap{$SharedCacheMap}{"in_memory"}{"0x4000"}=1; # mapped page?
# $LogHandle{$LogHandle}{"LogHandle"}="0x12345678";
# $Bcb{$Bcb}{"Bcb"}="0x12345678";
# $Bcb{$Bcb}{"SharedCacheMap"}="0x12345678";
if $Bcb{$pin}->{"by"} eq "CcPinMappedData";
}
}
+ else {
+ warn "unpin of pin Bcb $Bcb of SharedCacheMap ".$CObject->{"SharedCacheMap"}
+ ." although FileOffset ".$BObject->{"FileOffset"}." not in_memory"
+ if !($CObject->{"in_memory"}{$BObject->{"FileOffset"}});
+ # Do not: delete $CObject->{"in_memory"}{$BObject->{"FileOffset"}};
+ # as Cache Manager is not forced to drop it.
+# warn "UNMARK: SharedCacheMap ".$CObject->{"SharedCacheMap"}." FileOffset ".$BObject->{"FileOffset"};
+ }
for my $ref ($BObject->{"type"} eq "map" ? \$CObject->{"map"} : \$CObject->{"pin"}{$BObject->{"FileOffset"}}) {
warn "Final unpin but ".$BObject->{"type"}." Bcb $Bcb not registered"
." in SharedCacheMap ".$CObject->{"SharedCacheMap"}." ref ".($$ref || "<undef>")
$Object->{"FileOffset"}=tohex(eval($Object->{"FileOffset"})-$shift);
$Object->{"Buffer"}=tohex(eval($Buffer)-$shift);
+ warn "pin_new_leave() while FileOffset ".$Object->{"FileOffset"}." not in_memory"
+ ." of SharedCacheMap ".$CObject->{"SharedCacheMap"}
+ if !$CObject->{"in_memory"}{$Object->{"FileOffset"}};
+
my $ref=\$CObject->{"pin"}{$Object->{"FileOffset"}};
# There may not exist map bcb even if we are creating the new pin bcb.
Bcb_checkref $Object,$ref;
{
my($FileObject,$FileOffset,$Length)=@_;
+ return if !(my $CObject=CObject_from_FileObject $FileObject);
+ # Full pages do not need to be read:
+ if (!($FileOffset&0xFFF)) {
+ $CObject->{"in_memory"}{tohex $FileOffset}=1;
+ }
+
pin_new $FileObject,$FileOffset,$Length;
}
if $FlushToLsnRoutine;
return;
}
+ $CObject->{"in_memory"}{$ByteOffset}=1;
warn "Ambiguous matching Bcbs ".join(",",@Bcbs)
." to SharedCacheMap $SharedCacheMap WRITE ByteOffset $ByteOffset"
if @Bcbs>=2;
}
}
+sub IRP_MJ_READ_leave()
+{
+ # toplevel IRP_MJ_READ has no requirements
+ return if (0==@$EnterLeave);
+ my @stack=map({ $_->{"by"}=~/^IRP_MJ_/ ? () : $_ } @$EnterLeave);
+ my $opObject=$stack[0] if 1==@stack;
+ warn "IRP_MJ_READ not the expected function stack"
+ ." (".join(",",map({ $_->{"line_enter"}.":".$_->{"by"}; } @$EnterLeave)).")"
+ if !($opObject->{"by"} eq "CcMapData"
+ || $opObject->{"by"} eq "CcCopyRead"
+ || $opObject->{"by"} eq "CcMdlRead"
+ || $opObject->{"by"} eq "CcPinRead");
+ if ($opObject->{"by"} eq "CcMdlRead") {
+ do { warn "Length $_ not divisible by 0x1000" if eval($_)%0x1000; } for ($Object->{"READ"}{"Length"});
+ }
+ else {
+ do { warn "Length $_ not 0x1000" if eval($_)!=0x1000; } for ($Object->{"READ"}{"Length"});
+ }
+ my $SharedCacheMap=$Object->{"data"}[0]{"SharedCacheMap"};
+ return if !(my $CObject=CObject $SharedCacheMap);
+ for my $reloffs (0..eval($Object->{"READ"}{"Length"})/0x1000-1) {
+ my $ByteOffset=tohex(eval($Object->{"READ"}{"ByteOffset"})+$reloffs*0x1000);
+ # Do not: warn "Reading ByteOffset $ByteOffset into SharedCacheMap $SharedCacheMap twice"
+ # if $CObject->{"in_memory"}{$ByteOffset};
+ # as it may be still cached there as Cache Manager is not forced to drop it.
+ $CObject->{"in_memory"}{$ByteOffset}=1;
+# warn "MARK: SharedCacheMap ".$CObject->{"SharedCacheMap"}." FileOffset $ByteOffset";
+ }
+}
+
+sub CcPurgeCacheSection($$$$$)
+{
+my($SectionObjectPointer,$SharedCacheMap,$FileOffset,$Length,$UninitializeCacheMaps)=@_;
+
+ return if !(my $CObject=CObject $SharedCacheMap);
+ warn "Unexpected UninitializeCacheMaps $UninitializeCacheMaps" if $UninitializeCacheMaps ne "0";
+ my $all=($FileOffset eq "0x".("F"x8) && !eval $Length);
+ warn "Not yet implemented ranged CcPurgeCacheSection()" if !$all;
+ do { warn "Existing map Bcb $_ during CcPurgeCacheSection()" if $_; } for ($CObject->{"map"});
+ do { warn "Existing pin Bcb $_ during CcPurgeCacheSection()" if $_; } for (values(%{$CObject->{"pin"}}));
+ delete $CObject->{"in_memory"};
+}
+
sub CcFlushCache($$$$)
{
my($SectionObjectPointer,$SharedCacheMap,$FileOffset,$Length)=@_;
}
next;
}
- elsif (my($ByteOffset,$Length)=
- /^WRITE: ByteOffset=($hex),Length=($hex)/) {
+ elsif (my($op,$ByteOffset,$Length)=
+ /^(READ|WRITE): ByteOffset=($hex),Length=($hex)/) {
my $aref=$EnterLeave{$ProcessThread};
warn "Empty stack during 'data' line" if !($Object=${$aref}[$#$aref]);
- $Object->{"WRITE"}={
+ $Object->{$op}={
"ByteOffset"=>$ByteOffset,
"Length"=>$Length,
};
next;
}
+ if (/^leave: IRP_MJ_READ\b/) {
+ IRP_MJ_READ_leave;
+ next;
+ }
+
+ if (my($SectionObjectPointer,$SharedCacheMap,$FileOffset,$Length,$UninitializeCacheMaps)=
+ /^enter: CcPurgeCacheSection: SectionObjectPointer=($hex),->SharedCacheMap=($hex),FileOffset=($hex),Length=($hex),UninitializeCacheMaps=([01])/) {
+ CcPurgeCacheSection $SectionObjectPointer,$SharedCacheMap,$FileOffset,$Length,$UninitializeCacheMaps;
+ next;
+ }
+
if (/^leave: IRP_MJ_WRITE\b/) {
IRP_MJ_WRITE_leave;
next;