| // SPDX-License-Identifier: GPL-2.0 | |
| /* | |
| * This tool is used by the utimer test, and it allows us to | |
| * count the ticks of a global timer in a certain time frame | |
| * (which is set by `timeout` parameter). | |
| * | |
| * Author: Ivan Orlov <ivan.orlov0322@gmail.com> | |
| */ | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <alsa/asoundlib.h> | |
| #include <time.h> | |
| static int ticked; | |
| static void async_callback(snd_async_handler_t *ahandler) | |
| { | |
| ticked++; | |
| } | |
| static char timer_name[64]; | |
| static void bind_to_timer(int device, int subdevice, int timeout) | |
| { | |
| snd_timer_t *handle; | |
| snd_timer_params_t *params; | |
| snd_async_handler_t *ahandler; | |
| time_t end; | |
| sprintf(timer_name, "hw:CLASS=%d,SCLASS=%d,DEV=%d,SUBDEV=%d", | |
| SND_TIMER_CLASS_GLOBAL, SND_TIMER_SCLASS_NONE, | |
| device, subdevice); | |
| snd_timer_params_alloca(¶ms); | |
| if (snd_timer_open(&handle, timer_name, SND_TIMER_OPEN_NONBLOCK) < 0) { | |
| perror("Can't open the timer"); | |
| exit(EXIT_FAILURE); | |
| } | |
| snd_timer_params_set_auto_start(params, 1); | |
| snd_timer_params_set_ticks(params, 1); | |
| if (snd_timer_params(handle, params) < 0) { | |
| perror("Can't set timer params"); | |
| exit(EXIT_FAILURE); | |
| } | |
| if (snd_async_add_timer_handler(&ahandler, handle, async_callback, NULL) < 0) { | |
| perror("Can't create a handler"); | |
| exit(EXIT_FAILURE); | |
| } | |
| end = time(NULL) + timeout; | |
| if (snd_timer_start(handle) < 0) { | |
| perror("Failed to start the timer"); | |
| exit(EXIT_FAILURE); | |
| } | |
| printf("Timer has started\n"); | |
| while (time(NULL) <= end) { | |
| /* | |
| * Waiting for the timeout to elapse. Can't use sleep here, as it gets | |
| * constantly interrupted by the signal from the timer (SIGIO) | |
| */ | |
| } | |
| snd_timer_stop(handle); | |
| snd_timer_close(handle); | |
| } | |
| int main(int argc, char *argv[]) | |
| { | |
| int device, subdevice, timeout; | |
| if (argc < 4) { | |
| perror("Usage: %s <device> <subdevice> <timeout>"); | |
| return EXIT_FAILURE; | |
| } | |
| setlinebuf(stdout); | |
| device = atoi(argv[1]); | |
| subdevice = atoi(argv[2]); | |
| timeout = atoi(argv[3]); | |
| bind_to_timer(device, subdevice, timeout); | |
| printf("Total ticks count: %d\n", ticked); | |
| return EXIT_SUCCESS; | |
| } |