88 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			88 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| // 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;
 | |
| }
 |