Skip to content

Commit 9584752

Browse files
authored
Merge c195a4e into c0ff306
2 parents c0ff306 + c195a4e commit 9584752

17 files changed

+257
-42
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
- Improved performance serializing profiling data (#2863)
1212
- Possible crash in Core Data tracking (#2865)
1313
- Ensure the current GPU frame rate is always reported for concurrent transaction profiling metrics (#2929)
14+
- Move profiler metric collection to a background queue (#2956)
1415

1516
## 8.5.0
1617

Sentry.xcodeproj/project.pbxproj

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,12 @@
636636
84A8891C28DBD28900C51DFD /* SentryDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 84A8891A28DBD28900C51DFD /* SentryDevice.h */; };
637637
84A8891D28DBD28900C51DFD /* SentryDevice.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84A8891B28DBD28900C51DFD /* SentryDevice.mm */; };
638638
84A8892128DBD8D600C51DFD /* SentryDeviceTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84A8892028DBD8D600C51DFD /* SentryDeviceTests.mm */; };
639+
84AC61D229F7541E009EEF61 /* SentryDispatchSourceWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 84AC61D029F7541E009EEF61 /* SentryDispatchSourceWrapper.h */; };
640+
84AC61D329F7541E009EEF61 /* SentryDispatchSourceWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 84AC61D129F7541E009EEF61 /* SentryDispatchSourceWrapper.m */; };
641+
84AC61D629F75A98009EEF61 /* SentryDispatchFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 84AC61D429F75A98009EEF61 /* SentryDispatchFactory.h */; };
642+
84AC61D729F75A98009EEF61 /* SentryDispatchFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = 84AC61D529F75A98009EEF61 /* SentryDispatchFactory.m */; };
643+
84AC61D929F7643B009EEF61 /* TestDispatchFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84AC61D829F7643B009EEF61 /* TestDispatchFactory.swift */; };
644+
84AC61DB29F7654A009EEF61 /* TestDispatchSourceWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84AC61DA29F7654A009EEF61 /* TestDispatchSourceWrapper.swift */; };
639645
84AF45A629A7FFA500FBB177 /* SentryTracerConcurrency.h in Headers */ = {isa = PBXBuildFile; fileRef = 84AF45A429A7FFA500FBB177 /* SentryTracerConcurrency.h */; };
640646
84AF45A729A7FFA500FBB177 /* SentryTracerConcurrency.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84AF45A529A7FFA500FBB177 /* SentryTracerConcurrency.mm */; };
641647
84B7FA3529B285FC00AD93B1 /* Sentry.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63AA759B1EB8AEF500D153DE /* Sentry.framework */; };
@@ -1553,6 +1559,12 @@
15531559
84A8891A28DBD28900C51DFD /* SentryDevice.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryDevice.h; path = include/SentryDevice.h; sourceTree = "<group>"; };
15541560
84A8891B28DBD28900C51DFD /* SentryDevice.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = SentryDevice.mm; sourceTree = "<group>"; };
15551561
84A8892028DBD8D600C51DFD /* SentryDeviceTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = SentryDeviceTests.mm; sourceTree = "<group>"; };
1562+
84AC61D029F7541E009EEF61 /* SentryDispatchSourceWrapper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryDispatchSourceWrapper.h; path = include/SentryDispatchSourceWrapper.h; sourceTree = "<group>"; };
1563+
84AC61D129F7541E009EEF61 /* SentryDispatchSourceWrapper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryDispatchSourceWrapper.m; sourceTree = "<group>"; };
1564+
84AC61D429F75A98009EEF61 /* SentryDispatchFactory.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryDispatchFactory.h; path = include/SentryDispatchFactory.h; sourceTree = "<group>"; };
1565+
84AC61D529F75A98009EEF61 /* SentryDispatchFactory.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryDispatchFactory.m; sourceTree = "<group>"; };
1566+
84AC61D829F7643B009EEF61 /* TestDispatchFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestDispatchFactory.swift; sourceTree = "<group>"; };
1567+
84AC61DA29F7654A009EEF61 /* TestDispatchSourceWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestDispatchSourceWrapper.swift; sourceTree = "<group>"; };
15561568
84AF45A429A7FFA500FBB177 /* SentryTracerConcurrency.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryTracerConcurrency.h; path = include/SentryTracerConcurrency.h; sourceTree = "<group>"; };
15571569
84AF45A529A7FFA500FBB177 /* SentryTracerConcurrency.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = SentryTracerConcurrency.mm; sourceTree = "<group>"; };
15581570
84B7FA3B29B2866200AD93B1 /* SentryTestUtils-ObjC-BridgingHeader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SentryTestUtils-ObjC-BridgingHeader.h"; sourceTree = "<group>"; };
@@ -1835,6 +1847,10 @@
18351847
638DC99F1EBC6B6400A66E41 /* SentryRequestOperation.m */,
18361848
7BDB03B6251364F800BAE198 /* SentryDispatchQueueWrapper.h */,
18371849
7BDB03BA2513652900BAE198 /* SentryDispatchQueueWrapper.m */,
1850+
84AC61D029F7541E009EEF61 /* SentryDispatchSourceWrapper.h */,
1851+
84AC61D429F75A98009EEF61 /* SentryDispatchFactory.h */,
1852+
84AC61D529F75A98009EEF61 /* SentryDispatchFactory.m */,
1853+
84AC61D129F7541E009EEF61 /* SentryDispatchSourceWrapper.m */,
18381854
0AAE202028ED9BCC00D0CD80 /* SentryReachability.h */,
18391855
0AAE201D28ED9B9400D0CD80 /* SentryReachability.m */,
18401856
);
@@ -3105,6 +3121,8 @@
31053121
isa = PBXGroup;
31063122
children = (
31073123
7BD47B4C268F0B080076A663 /* ClearTestState.swift */,
3124+
84AC61D829F7643B009EEF61 /* TestDispatchFactory.swift */,
3125+
84AC61DA29F7654A009EEF61 /* TestDispatchSourceWrapper.swift */,
31083126
84A5D75A29D5170700388BFA /* TimeInterval+Sentry.swift */,
31093127
7B30B68126527C55006B2752 /* TestDisplayLinkWrapper.swift */,
31103128
8E25C97425F8511A00DC215B /* TestRandom.swift */,
@@ -3361,6 +3379,7 @@
33613379
7B82D54524E2A05500EE670F /* SentryId.h in Headers */,
33623380
D867063D27C3BC2400048851 /* SentryCoreDataTrackingIntegration.h in Headers */,
33633381
0A2D8D5D289815EB008720F6 /* SentryBaseIntegration.h in Headers */,
3382+
84AC61D629F75A98009EEF61 /* SentryDispatchFactory.h in Headers */,
33643383
63FE716520DA4C1100CDBAE8 /* SentryCrashMemory.h in Headers */,
33653384
63FE713F20DA4C1100CDBAE8 /* SentryCrashStackCursor_SelfThread.h in Headers */,
33663385
639FCFA41EBC809A00778193 /* SentryStacktrace.h in Headers */,
@@ -3485,6 +3504,7 @@
34853504
632331F9240506DF008D91D6 /* SentryScope+Private.h in Headers */,
34863505
D8603DD8284F894C000E1227 /* SentryBaggage.h in Headers */,
34873506
03F84D2127DD414C008FE43F /* SentrySamplingProfiler.hpp in Headers */,
3507+
84AC61D229F7541E009EEF61 /* SentryDispatchSourceWrapper.h in Headers */,
34883508
63FE712B20DA4C1100CDBAE8 /* SentryCrashStackCursor.h in Headers */,
34893509
D8C67E9C28000E24007E326E /* SentryScreenshot.h in Headers */,
34903510
7BA61CBF247CEA8100C130A8 /* SentryFormatter.h in Headers */,
@@ -3894,6 +3914,7 @@
38943914
63FE712920DA4C1000CDBAE8 /* SentryCrashCPU_arm.c in Sources */,
38953915
03F84D3427DD4191008FE43F /* SentryThreadMetadataCache.cpp in Sources */,
38963916
7B88F30024BC5A7D00ADF90A /* SentrySdkInfo.m in Sources */,
3917+
84AC61D729F75A98009EEF61 /* SentryDispatchFactory.m in Sources */,
38973918
15360CD62432832400112302 /* SentryAutoSessionTrackingIntegration.m in Sources */,
38983919
7B63459F280EBA7200CFA05A /* SentryUIEventTracker.m in Sources */,
38993920
7BF9EF782722B35D00B5BBEF /* SentrySubClassFinder.m in Sources */,
@@ -4010,6 +4031,7 @@
40104031
7BB65501253DC1B500887E87 /* SentryUserFeedback.m in Sources */,
40114032
7D5C441A237C2E1F00DAB0A3 /* SentrySDK.m in Sources */,
40124033
7D65260E237F649E00113EA2 /* SentryScope.m in Sources */,
4034+
84AC61D329F7541E009EEF61 /* SentryDispatchSourceWrapper.m in Sources */,
40134035
63FE712D20DA4C1100CDBAE8 /* SentryCrashJSONCodecObjC.m in Sources */,
40144036
7BBD18932449BEDD00427C76 /* SentryDefaultRateLimits.m in Sources */,
40154037
7BD729982463E93500EA3610 /* SentryDateUtil.m in Sources */,
@@ -4341,6 +4363,7 @@
43414363
84B7FA4229B28CDE00AD93B1 /* TestCurrentDateProvider.swift in Sources */,
43424364
84B7FA3F29B28BAD00AD93B1 /* TestTransport.swift in Sources */,
43434365
84A5D75B29D5170700388BFA /* TimeInterval+Sentry.swift in Sources */,
4366+
84AC61D929F7643B009EEF61 /* TestDispatchFactory.swift in Sources */,
43444367
8431F01929B2852D00D8DC56 /* Invocation.swift in Sources */,
43454368
84B7FA4629B2935F00AD93B1 /* ClearTestState.swift in Sources */,
43464369
8431F01529B2851500D8DC56 /* TestSentryNSTimerWrapper.swift in Sources */,
@@ -4352,6 +4375,7 @@
43524375
8431F01B29B2852D00D8DC56 /* Logger.swift in Sources */,
43534376
8431F01829B2852D00D8DC56 /* TypeMapping.swift in Sources */,
43544377
84B7FA4529B2926900AD93B1 /* TestDisplayLinkWrapper.swift in Sources */,
4378+
84AC61DB29F7654A009EEF61 /* TestDispatchSourceWrapper.swift in Sources */,
43554379
8431F01729B2851500D8DC56 /* TestSentrySystemWrapper.swift in Sources */,
43564380
84B7FA4129B28CD200AD93B1 /* TestSentryDispatchQueueWrapper.swift in Sources */,
43574381
84B7FA3E29B28ADD00AD93B1 /* TestClient.swift in Sources */,

SentryTestUtils/SentryTestUtils-ObjC-BridgingHeader.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
#import "SentryCurrentDateProvider.h"
99
#import "SentryDefines.h"
1010
#import "SentryDependencyContainer.h"
11+
#import "SentryDispatchFactory.h"
1112
#import "SentryDispatchQueueWrapper.h"
13+
#import "SentryDispatchSourceWrapper.h"
1214
#import "SentryDisplayLinkWrapper.h"
1315
#import "SentryEnvelope.h"
1416
#import "SentryFileManager.h"
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import Foundation
2+
import Sentry
3+
4+
public class TestDispatchFactory: SentryDispatchFactory {
5+
public var vendedSourceHandler: ((TestDispatchSourceWrapper) -> Void)?
6+
public var vendedQueueHandler: ((TestSentryDispatchQueueWrapper) -> Void)?
7+
8+
public override func queue(withName name: UnsafePointer<CChar>, attributes: __OS_dispatch_queue_attr) -> SentryDispatchQueueWrapper {
9+
let queue = TestSentryDispatchQueueWrapper(name: name, attributes: attributes)
10+
vendedQueueHandler?(queue)
11+
return queue
12+
}
13+
14+
public override func source(withInterval interval: UInt64, leeway: UInt64, queue queueWrapper: SentryDispatchQueueWrapper, eventHandler: @escaping () -> Void) -> SentryDispatchSourceWrapper {
15+
let source = TestDispatchSourceWrapper(eventHandler: eventHandler)
16+
vendedSourceHandler?(source)
17+
return source
18+
}
19+
20+
public override func source(withInterval interval: UInt64, leeway: UInt64, queueName: UnsafePointer<CChar>, attributes: __OS_dispatch_queue_attr, eventHandler: @escaping () -> Void) -> SentryDispatchSourceWrapper {
21+
let source = TestDispatchSourceWrapper(eventHandler: eventHandler)
22+
vendedSourceHandler?(source)
23+
return source
24+
}
25+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import Foundation
2+
import Sentry
3+
4+
public class TestDispatchSourceWrapper: SentryDispatchSourceWrapper {
5+
public struct Override {
6+
public var eventHandler: (() -> Void)?
7+
}
8+
public var overrides = Override()
9+
10+
public init(eventHandler: @escaping () -> Void) {
11+
self.overrides.eventHandler = eventHandler
12+
super.init()
13+
}
14+
15+
public override func cancel() {
16+
// no-op
17+
}
18+
19+
public func fire() {
20+
self.overrides.eventHandler?()
21+
}
22+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#import "SentryDispatchFactory.h"
2+
#import "SentryDispatchQueueWrapper.h"
3+
#import "SentryDispatchSourceWrapper.h"
4+
5+
@implementation SentryDispatchFactory
6+
7+
- (SentryDispatchQueueWrapper *)queueWithName:(const char *)name
8+
attributes:(dispatch_queue_attr_t)attributes
9+
{
10+
return [[SentryDispatchQueueWrapper alloc] initWithName:name attributes:attributes];
11+
}
12+
13+
- (SentryDispatchSourceWrapper *)sourceWithInterval:(uint64_t)interval
14+
leeway:(uint64_t)leeway
15+
queue:(SentryDispatchQueueWrapper *)queueWrapper
16+
eventHandler:(void (^)(void))eventHandler
17+
{
18+
return [[SentryDispatchSourceWrapper alloc] initTimerWithInterval:interval
19+
leeway:leeway
20+
queue:queueWrapper
21+
eventHandler:eventHandler];
22+
}
23+
24+
- (SentryDispatchSourceWrapper *)sourceWithInterval:(uint64_t)interval
25+
leeway:(uint64_t)leeway
26+
queueName:(const char *)queueName
27+
attributes:(dispatch_queue_attr_t)attributes
28+
eventHandler:(void (^)(void))eventHandler
29+
{
30+
return [self sourceWithInterval:interval
31+
leeway:leeway
32+
queue:[self queueWithName:queueName attributes:attributes]
33+
eventHandler:eventHandler];
34+
}
35+
36+
@end

Sources/Sentry/SentryDispatchQueueWrapper.m

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,7 @@
33

44
NS_ASSUME_NONNULL_BEGIN
55

6-
@implementation SentryDispatchQueueWrapper {
7-
// Don't use a normal property because on RN a user got a warning "Property with 'retain (or
8-
// strong)' attribute must be of object type". A dispatch queue is since iOS 6.0 an NSObject so
9-
// it should work with strong, but nevertheless, we use an instance variable to fix this
10-
// warning.
11-
dispatch_queue_t queue;
12-
}
6+
@implementation SentryDispatchQueueWrapper
137

148
- (instancetype)init
159
{
@@ -24,14 +18,14 @@ - (instancetype)init
2418
- (instancetype)initWithName:(const char *)name attributes:(dispatch_queue_attr_t)attributes;
2519
{
2620
if (self = [super init]) {
27-
queue = dispatch_queue_create(name, attributes);
21+
_queue = dispatch_queue_create(name, attributes);
2822
}
2923
return self;
3024
}
3125

3226
- (void)dispatchAsyncWithBlock:(void (^)(void))block
3327
{
34-
dispatch_async(queue, ^{
28+
dispatch_async(_queue, ^{
3529
@autoreleasepool {
3630
block();
3731
}
@@ -60,7 +54,7 @@ - (void)dispatchAfter:(NSTimeInterval)interval block:(dispatch_block_t)block
6054
{
6155
dispatch_time_t delta = (int64_t)(interval * NSEC_PER_SEC);
6256
dispatch_time_t when = dispatch_time(DISPATCH_TIME_NOW, delta);
63-
dispatch_after(when, queue, ^{
57+
dispatch_after(when, _queue, ^{
6458
@autoreleasepool {
6559
block();
6660
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#import "SentryDispatchSourceWrapper.h"
2+
#import "SentryDispatchQueueWrapper.h"
3+
4+
@implementation SentryDispatchSourceWrapper {
5+
SentryDispatchQueueWrapper *_queueWrapper;
6+
dispatch_source_t _source;
7+
}
8+
9+
- (instancetype)initTimerWithInterval:(uint64_t)interval
10+
leeway:(uint64_t)leeway
11+
queue:(SentryDispatchQueueWrapper *)queueWrapper
12+
eventHandler:(void (^)(void))eventHandler
13+
{
14+
if (!(self = [super init])) {
15+
return nil;
16+
}
17+
18+
_queueWrapper = queueWrapper;
19+
_source = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queueWrapper.queue);
20+
dispatch_source_set_event_handler(_source, eventHandler);
21+
dispatch_source_set_timer(
22+
_source, dispatch_time(DISPATCH_TIME_NOW, interval), interval, leeway);
23+
dispatch_resume(_source);
24+
return self;
25+
}
26+
27+
- (void)cancel
28+
{
29+
dispatch_cancel(_source);
30+
}
31+
32+
@end

Sources/Sentry/SentryMetricProfiler.mm

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
#if SENTRY_TARGET_PROFILING_SUPPORTED
44

55
# import "SentryCurrentDate.h"
6+
# import "SentryDispatchFactory.h"
7+
# import "SentryDispatchQueueWrapper.h"
8+
# import "SentryDispatchSourceWrapper.h"
69
# import "SentryEvent+Private.h"
710
# import "SentryFormatter.h"
811
# import "SentryLog.h"
@@ -23,19 +26,18 @@ @interface SentryMetricReading : NSObject
2326
@implementation SentryMetricReading
2427
@end
2528

26-
/**
27-
* Currently set to 10 Hz as we don't anticipate much utility out of a higher resolution when
28-
* sampling CPU usage and memory footprint, and we want to minimize the overhead of making the
29-
* necessary system calls to gather that information.
30-
*/
31-
static const NSTimeInterval kSentryMetricProfilerTimeseriesInterval = 0.1;
32-
3329
NSString *const kSentryMetricProfilerSerializationKeyMemoryFootprint = @"memory_footprint";
3430
NSString *const kSentryMetricProfilerSerializationKeyCPUUsageFormat = @"cpu_usage_%d";
3531

3632
NSString *const kSentryMetricProfilerSerializationUnitBytes = @"byte";
3733
NSString *const kSentryMetricProfilerSerializationUnitPercentage = @"percent";
3834

35+
// Currently set to 10 Hz as we don't anticipate much utility out of a higher resolution when
36+
// sampling CPU usage and memory footprint, and we want to minimize the overhead of making the
37+
// necessary system calls to gather that information. This is currently roughly 10% of the
38+
// backtrace profiler's resolution.
39+
static uint64_t frequencyHz = 10;
40+
3941
namespace {
4042
/**
4143
* @return a dictionary containing all the metric values recorded during the transaction, or @c nil
@@ -74,11 +76,11 @@ @implementation SentryMetricReading
7476
} // namespace
7577

7678
@implementation SentryMetricProfiler {
77-
NSTimer *_timer;
79+
SentryDispatchSourceWrapper *_timer;
7880

7981
SentryNSProcessInfoWrapper *_processInfoWrapper;
8082
SentrySystemWrapper *_systemWrapper;
81-
SentryNSTimerWrapper *_timerWrapper;
83+
SentryDispatchFactory *_dispatchFactory;
8284

8385
/// arrays of readings keyed on NSNumbers representing the core number for the set of readings
8486
NSMutableDictionary<NSNumber *, NSMutableArray<SentryMetricReading *> *> *_cpuUsage;
@@ -88,7 +90,7 @@ @implementation SentryMetricProfiler {
8890

8991
- (instancetype)initWithProcessInfoWrapper:(SentryNSProcessInfoWrapper *)processInfoWrapper
9092
systemWrapper:(SentrySystemWrapper *)systemWrapper
91-
timerWrapper:(SentryNSTimerWrapper *)timerWrapper
93+
dispatchFactory:(nonnull SentryDispatchFactory *)dispatchFactory
9294
{
9395
if (self = [super init]) {
9496
_cpuUsage =
@@ -102,7 +104,7 @@ - (instancetype)initWithProcessInfoWrapper:(SentryNSProcessInfoWrapper *)process
102104

103105
_systemWrapper = systemWrapper;
104106
_processInfoWrapper = processInfoWrapper;
105-
_timerWrapper = timerWrapper;
107+
_dispatchFactory = dispatchFactory;
106108

107109
_memoryFootprint = [NSMutableArray<SentryMetricReading *> array];
108110
}
@@ -123,7 +125,7 @@ - (void)start
123125

124126
- (void)stop
125127
{
126-
[_timer invalidate];
128+
[_timer cancel];
127129
}
128130

129131
- (NSMutableDictionary<NSString *, id> *)serializeForTransaction:(SentryTransaction *)transaction
@@ -157,12 +159,18 @@ - (void)stop
157159
- (void)registerSampler
158160
{
159161
__weak auto weakSelf = self;
160-
_timer = [_timerWrapper scheduledTimerWithTimeInterval:kSentryMetricProfilerTimeseriesInterval
161-
repeats:YES
162-
block:^(NSTimer *_Nonnull timer) {
163-
[weakSelf recordCPUPercentagePerCore];
164-
[weakSelf recordMemoryFootprint];
165-
}];
162+
const auto intervalNs = (uint64_t)1e9 / frequencyHz;
163+
const auto leewayNs = intervalNs / 2;
164+
_timer =
165+
[_dispatchFactory sourceWithInterval:intervalNs
166+
leeway:leewayNs
167+
queueName:"io.sentry.metric-profiler"
168+
attributes:dispatch_queue_attr_make_with_qos_class(
169+
DISPATCH_QUEUE_CONCURRENT, QOS_CLASS_UTILITY, 0)
170+
eventHandler:^{
171+
[weakSelf recordCPUPercentagePerCore];
172+
[weakSelf recordMemoryFootprint];
173+
}];
166174
}
167175

168176
- (void)recordMemoryFootprint

0 commit comments

Comments
 (0)