00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
#include "ki.h"
00028
00029
00030
00031
00032
00033
00034 #define ASSERT_PROFILE(E) { \
00035
ASSERT((E)->Type == ProfileObject); \
00036
}
00037
00038
00039
00040
00041 typedef struct _KACTIVE_PROFILE_SOURCE {
00042 LIST_ENTRY
ListEntry;
00043 KPROFILE_SOURCE
Source;
00044 KAFFINITY
Affinity;
00045 ULONG
ProcessorCount[1];
00046 }
KACTIVE_PROFILE_SOURCE, *
PKACTIVE_PROFILE_SOURCE;
00047
00048
00049
00050
00051
VOID
00052
KiStartProfileInterrupt (
00053 IN PKIPI_CONTEXT SignalDone,
00054 IN PVOID Parameter1,
00055 IN PVOID Parameter2,
00056 IN PVOID Parameter3
00057 );
00058
00059
VOID
00060
KiStopProfileInterrupt (
00061 IN PKIPI_CONTEXT SignalDone,
00062 IN PVOID Parameter1,
00063 IN PVOID Parameter2,
00064 IN PVOID Parameter3
00065 );
00066
00067
00068
VOID
00069 KeInitializeProfile (
00070 IN
PKPROFILE Profile,
00071 IN
PKPROCESS Process OPTIONAL,
00072 IN PVOID RangeBase,
00073 IN SIZE_T RangeSize,
00074 IN ULONG BucketSize,
00075 IN ULONG Segment,
00076 IN KPROFILE_SOURCE ProfileSource,
00077 IN KAFFINITY ProfileAffinity
00078 )
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 {
00123
00124
#if !defined(i386)
00125
00126
ASSERT(Segment == 0);
00127
00128
#endif
00129
00130
00131
00132
00133
00134 Profile->Type =
ProfileObject;
00135 Profile->Size =
sizeof(
KPROFILE);
00136
00137
00138
00139
00140
00141
00142
if (ARGUMENT_PRESENT(Process)) {
00143 Profile->Process = Process;
00144
00145 }
else {
00146 Profile->Process =
NULL;
00147 }
00148
00149 Profile->RangeBase = RangeBase;
00150 Profile->RangeLimit = (PUCHAR)RangeBase + RangeSize;
00151 Profile->BucketShift = BucketSize - 2;
00152 Profile->Started =
FALSE;
00153 Profile->Segment = Segment;
00154 Profile->Source = (CSHORT)ProfileSource;
00155 Profile->Affinity = ProfileAffinity &
KeActiveProcessors;
00156
if (Profile->Affinity == 0) {
00157 Profile->Affinity =
KeActiveProcessors;
00158 }
00159
return;
00160 }
00161
00162 ULONG
00163 KeQueryIntervalProfile (
00164 IN KPROFILE_SOURCE ProfileSource
00165 )
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 {
00185
00186
HAL_PROFILE_SOURCE_INFORMATION ProfileSourceInfo;
00187 ULONG ReturnedLength;
00188
NTSTATUS Status;
00189
00190
if (ProfileSource == ProfileTime) {
00191
00192
00193
00194
00195
00196
return KiProfileInterval;
00197
00198 }
else if (ProfileSource == ProfileAlignmentFixup) {
00199
return KiProfileAlignmentFixupInterval;
00200
00201 }
else {
00202
00203
00204
00205
00206
00207 ProfileSourceInfo.
Source = ProfileSource;
00208
Status =
HalQuerySystemInformation(
HalProfileSourceInformation,
00209
sizeof(
HAL_PROFILE_SOURCE_INFORMATION),
00210 &ProfileSourceInfo,
00211 &ReturnedLength);
00212
00213
if (
NT_SUCCESS(
Status) && ProfileSourceInfo.
Supported) {
00214
return ProfileSourceInfo.
Interval;
00215
00216 }
else {
00217
return 0;
00218 }
00219 }
00220 }
00221
00222
VOID
00223 KeSetIntervalProfile (
00224 IN ULONG Interval,
00225 IN KPROFILE_SOURCE Source
00226 )
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 {
00248
00249
HAL_PROFILE_SOURCE_INTERVAL ProfileSourceInterval;
00250
00251
if (Source == ProfileTime) {
00252
00253
00254
00255
00256
00257
00258
00259
if (Interval < MINIMUM_PROFILE_INTERVAL) {
00260 Interval = MINIMUM_PROFILE_INTERVAL;
00261 }
00262
00263
00264
00265
00266
00267
KiProfileInterval = (ULONG)
KiIpiGenericCall(
HalSetProfileInterval, Interval);
00268
00269 }
else if (Source == ProfileAlignmentFixup) {
00270
KiProfileAlignmentFixupInterval = Interval;
00271
00272 }
else {
00273
00274
00275
00276
00277
00278 ProfileSourceInterval.
Source = Source;
00279 ProfileSourceInterval.
Interval = Interval;
00280
HalSetSystemInformation(
HalProfileSourceInterval,
00281
sizeof(
HAL_PROFILE_SOURCE_INTERVAL),
00282 &ProfileSourceInterval);
00283 }
00284
00285
return;
00286 }
00287
00288 BOOLEAN
00289 KeStartProfile (
00290 IN
PKPROFILE Profile,
00291 IN PULONG Buffer
00292 )
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324 {
00325
00326 KIRQL OldIrql, OldIrql2;
00327
PKPROCESS Process;
00328 BOOLEAN Started;
00329 KAFFINITY TargetProcessors;
00330 PKPRCB Prcb;
00331
PKACTIVE_PROFILE_SOURCE ActiveSource =
NULL;
00332
PKACTIVE_PROFILE_SOURCE CurrentActiveSource;
00333
PKACTIVE_PROFILE_SOURCE AllocatedPool;
00334 PLIST_ENTRY ListEntry;
00335 ULONG SourceSize;
00336 KAFFINITY AffinitySet;
00337 PULONG Reference;
00338
00339
ASSERT_PROFILE(Profile);
00340
ASSERT(KeGetCurrentIrql() <=
DISPATCH_LEVEL);
00341
00342
00343
00344
00345
00346 SourceSize =
sizeof(
KACTIVE_PROFILE_SOURCE) +
sizeof(ULONG) *
00347 (
KeNumberProcessors - 1);
00348 AllocatedPool =
ExAllocatePoolWithTag(
NonPagedPool, SourceSize, 'forP');
00349
if (AllocatedPool ==
NULL) {
00350
return(
TRUE);
00351 }
00352
00353
00354
00355
00356
00357
KeRaiseIrql (
DISPATCH_LEVEL, &OldIrql);
00358 Prcb =
KeGetCurrentPrcb();
00359
00360
00361
00362
00363
00364
KeRaiseIrql(
KiProfileIrql, &OldIrql2);
00365 KiAcquireSpinLock(&
KiProfileLock);
00366
00367
00368
00369
00370
00371 Started =
FALSE;
00372 AffinitySet = 0
L;
00373 TargetProcessors = 0
L;
00374
00375
00376
00377
00378
00379
00380
00381
00382
if (Profile->Started ==
FALSE) {
00383
00384 Started =
TRUE;
00385 Profile->Buffer =
Buffer;
00386 Profile->Started =
TRUE;
00387 Process = Profile->Process;
00388
if (Process !=
NULL) {
00389 InsertTailList(&Process->
ProfileListHead, &Profile->ProfileListEntry);
00390
00391 }
else {
00392 InsertTailList(&
KiProfileListHead, &Profile->ProfileListEntry);
00393 }
00394
00395
00396
00397
00398
00399
00400
00401
00402 ListEntry =
KiProfileSourceListHead.Flink;
00403
while (ListEntry != &
KiProfileSourceListHead) {
00404 CurrentActiveSource = CONTAINING_RECORD(ListEntry,
00405
KACTIVE_PROFILE_SOURCE,
00406 ListEntry);
00407
00408
if (CurrentActiveSource->
Source == Profile->Source) {
00409 ActiveSource = CurrentActiveSource;
00410
break;
00411 }
00412 ListEntry = ListEntry->Flink;
00413 }
00414
00415
if (ActiveSource ==
NULL) {
00416
00417
00418
00419
00420
00421
00422 ActiveSource = AllocatedPool;
00423 AllocatedPool =
NULL;
00424 RtlZeroMemory(ActiveSource, SourceSize);
00425 ActiveSource->
Source = Profile->Source;
00426 InsertHeadList(&
KiProfileSourceListHead, &ActiveSource->
ListEntry);
00427
if (Profile->Source == ProfileAlignmentFixup) {
00428
KiProfileAlignmentFixup =
TRUE;
00429 }
00430 }
00431
00432
00433
00434
00435
00436
00437 AffinitySet = Profile->Affinity;
00438 Reference = &ActiveSource->
ProcessorCount[0];
00439
while (AffinitySet != 0) {
00440
if (AffinitySet & 1) {
00441 *Reference = *Reference + 1;
00442 }
00443
00444 AffinitySet = AffinitySet >> 1;
00445 Reference = Reference + 1;
00446 }
00447
00448
00449
00450
00451
00452
00453 AffinitySet = Profile->Affinity & ~ActiveSource->
Affinity;
00454 TargetProcessors = AffinitySet & ~Prcb->SetMember;
00455
00456
00457
00458
00459
00460 ActiveSource->
Affinity |= Profile->Affinity;
00461 }
00462
00463
00464
00465
00466
00467
00468 KiReleaseSpinLock(&
KiProfileLock);
00469
KeLowerIrql(OldIrql2);
00470
00471
00472
00473
00474
00475
#if !defined(NT_UP)
00476
00477
if (TargetProcessors != 0) {
00478
KiIpiSendPacket(TargetProcessors,
00479
KiStartProfileInterrupt,
00480 (PVOID)Profile->Source,
00481
NULL,
00482
NULL);
00483 }
00484
00485
#endif
00486
00487
if (AffinitySet & Prcb->SetMember) {
00488
if (Profile->Source == ProfileAlignmentFixup) {
00489
KiEnableAlignmentExceptions();
00490 }
00491
HalStartProfileInterrupt(Profile->Source);
00492 }
00493
00494
#if !defined(NT_UP)
00495
00496
if (TargetProcessors != 0) {
00497
KiIpiStallOnPacketTargets(TargetProcessors);
00498 }
00499
00500
#endif
00501
00502
00503
00504
00505
00506
KeLowerIrql(OldIrql);
00507
00508
00509
00510
00511
00512
if (AllocatedPool !=
NULL) {
00513
ExFreePool(AllocatedPool);
00514 }
00515
00516
return Started;
00517 }
00518
00519 BOOLEAN
00520 KeStopProfile (
00521 IN
PKPROFILE Profile
00522 )
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546 {
00547
00548 KIRQL OldIrql, OldIrql2;
00549 BOOLEAN Stopped;
00550 KAFFINITY TargetProcessors;
00551 PKPRCB Prcb;
00552 BOOLEAN StopInterrupt =
TRUE;
00553 PLIST_ENTRY ListEntry;
00554
PKACTIVE_PROFILE_SOURCE ActiveSource;
00555
PKACTIVE_PROFILE_SOURCE PoolToFree=
NULL;
00556 KAFFINITY AffinitySet = 0;
00557 KAFFINITY CurrentProcessor;
00558 PULONG Reference;
00559
00560
ASSERT_PROFILE(Profile);
00561
ASSERT(KeGetCurrentIrql() <=
DISPATCH_LEVEL);
00562
00563
00564
00565
00566
00567
KeRaiseIrql (
DISPATCH_LEVEL, &OldIrql);
00568 Prcb =
KeGetCurrentPrcb();
00569
00570
00571
00572
00573
00574
KeRaiseIrql(
KiProfileIrql, &OldIrql2);
00575 KiAcquireSpinLock(&
KiProfileLock);
00576
00577
00578
00579
00580
00581 Stopped =
FALSE;
00582 AffinitySet = 0
L;
00583 TargetProcessors = 0
L;
00584
00585
00586
00587
00588
00589
00590
00591
00592
if (Profile->Started !=
FALSE) {
00593
00594 Stopped =
TRUE;
00595 Profile->Started =
FALSE;
00596 RemoveEntryList(&Profile->ProfileListEntry);
00597
00598
00599
00600
00601
00602
00603 ListEntry =
KiProfileSourceListHead.Flink;
00604
do {
00605
ASSERT(ListEntry != &
KiProfileSourceListHead);
00606 ActiveSource = CONTAINING_RECORD(ListEntry,
00607
KACTIVE_PROFILE_SOURCE,
00608 ListEntry);
00609 ListEntry = ListEntry->Flink;
00610 }
while ( ActiveSource->
Source != Profile->Source );
00611
00612
00613
00614
00615
00616
00617
00618 CurrentProcessor = 1;
00619 TargetProcessors = 0;
00620 AffinitySet = Profile->Affinity;
00621 Reference = &ActiveSource->
ProcessorCount[0];
00622
while (AffinitySet != 0) {
00623
if (AffinitySet & 1) {
00624 *Reference = *Reference - 1;
00625
if (*Reference == 0) {
00626 TargetProcessors = TargetProcessors | CurrentProcessor;
00627 }
00628 }
00629
00630 AffinitySet = AffinitySet >> 1;
00631 Reference = Reference + 1;
00632 CurrentProcessor = CurrentProcessor << 1;
00633 }
00634
00635
00636
00637
00638
00639
00640 AffinitySet = TargetProcessors;
00641 TargetProcessors = AffinitySet & ~Prcb->SetMember;
00642
00643
00644
00645
00646
00647 ActiveSource->
Affinity &= ~AffinitySet;
00648
00649
00650
00651
00652
00653
00654
if (ActiveSource->
Affinity == 0) {
00655 RemoveEntryList(&ActiveSource->
ListEntry);
00656 PoolToFree = ActiveSource;
00657
if (Profile->Source == ProfileAlignmentFixup) {
00658
KiProfileAlignmentFixup =
FALSE;
00659 }
00660 }
00661 }
00662
00663
00664
00665
00666
00667
00668 KiReleaseSpinLock(&
KiProfileLock);
00669
KeLowerIrql(OldIrql2);
00670
00671
00672
00673
00674
00675
#if !defined(NT_UP)
00676
00677
if (TargetProcessors != 0) {
00678
KiIpiSendPacket(TargetProcessors,
00679
KiStopProfileInterrupt,
00680 (PVOID)Profile->Source,
00681
NULL,
00682
NULL);
00683 }
00684
00685
#endif
00686
00687
if (AffinitySet & Prcb->SetMember) {
00688
if (Profile->Source == ProfileAlignmentFixup) {
00689
KiDisableAlignmentExceptions();
00690 }
00691
HalStopProfileInterrupt(Profile->Source);
00692 }
00693
00694
#if !defined(NT_UP)
00695
00696
if (TargetProcessors != 0) {
00697
KiIpiStallOnPacketTargets(TargetProcessors);
00698 }
00699
00700
#endif
00701
00702
00703
00704
00705
00706
KeLowerIrql (OldIrql);
00707
00708
00709
00710
00711
00712
00713
if (PoolToFree !=
NULL) {
00714
ExFreePool(PoolToFree);
00715 }
00716
00717
return Stopped;
00718 }
00719
00720
#if !defined(NT_UP)
00721
00722
00723
VOID
00724 KiStopProfileInterrupt (
00725 IN PKIPI_CONTEXT SignalDone,
00726 IN PVOID Parameter1,
00727 IN PVOID Parameter2,
00728 IN PVOID Parameter3
00729 )
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753 {
00754
00755 KPROFILE_SOURCE ProfileSource;
00756
00757
00758
00759
00760
00761
00762 ProfileSource = (KPROFILE_SOURCE) PtrToUlong(Parameter1);
00763
if (ProfileSource == ProfileAlignmentFixup) {
00764
KiDisableAlignmentExceptions();
00765 }
00766
HalStopProfileInterrupt(ProfileSource);
00767
KiIpiSignalPacketDone(SignalDone);
00768
return;
00769 }
00770
00771
VOID
00772 KiStartProfileInterrupt (
00773 IN PKIPI_CONTEXT SignalDone,
00774 IN PVOID Parameter1,
00775 IN PVOID Parameter2,
00776 IN PVOID Parameter3
00777 )
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801 {
00802
00803 KPROFILE_SOURCE ProfileSource;
00804
00805
00806
00807
00808
00809
00810 ProfileSource = (KPROFILE_SOURCE)PtrToUlong(Parameter1);
00811
if (ProfileSource == ProfileAlignmentFixup) {
00812
KiEnableAlignmentExceptions();
00813 }
00814
HalStartProfileInterrupt(ProfileSource);
00815
KiIpiSignalPacketDone(SignalDone);
00816
return;
00817 }
00818
00819
#endif