1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-27 01:31:42 +00:00

Merge pull request #612 from TomHarte/HighPrecisionTimer

Sketches a high-precision timer class.
This commit is contained in:
Thomas Harte 2019-03-10 17:47:20 -04:00 committed by GitHub
commit 48d1d27067
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 64 additions and 0 deletions

View File

@ -0,0 +1,27 @@
//
// CSHighPrecisionTimer.h
// Clock Signal
//
// Created by Thomas Harte on 07/03/2019.
// Copyright © 2019 Thomas Harte. All rights reserved.
//
#import <Foundation/Foundation.h>
/*!
Provides a high-precision timer; provide it with a block and an
interval, and it will ensure the block is performed as regularly
as the system will allow at the specified intervals.
The block will be executed on an arbitrary thread.
*/
@interface CSHighPrecisionTimer: NSObject
/// Initialises a new instance of the high precision timer; the timer will begin
/// ticking immediately.
- (instancetype)initWithTask:(dispatch_block_t)task interval:(uint64_t)interval;
/// Stops the timer.
- (void)invalidate;
@end

View File

@ -0,0 +1,37 @@
//
// CSHighPrecisionTimer.m
// Clock Signal
//
// Created by Thomas Harte on 07/03/2019.
// Copyright © 2019 Thomas Harte. All rights reserved.
//
#import "CSHighPrecisionTimer.h"
@implementation CSHighPrecisionTimer {
dispatch_source_t _timer;
dispatch_queue_t _queue;
}
- (instancetype)initWithTask:(dispatch_block_t)task interval:(uint64_t)interval {
self = [super init];
if(self) {
_queue = dispatch_queue_create("High precision timer queue", DISPATCH_QUEUE_SERIAL);
_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, _queue);
if(_timer) {
dispatch_source_set_timer(_timer, dispatch_walltime(NULL, 0), interval, 0);
dispatch_source_set_event_handler(_timer, task);
// TODO: dispatch_activate is preferred to dispatch_resume, but arrives only
// as of macOS 10.12. So switch if/when upping the OS requirements.
dispatch_resume(_timer);
}
}
return self;
}
- (void)invalidate {
dispatch_suspend(_timer);
}
@end