mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	ringbuffer: add stress test
This commit is contained in:
		
							parent
							
								
									82d5ca1edc
								
							
						
					
					
						commit
						63d060a63e
					
				
					 2 changed files with 127 additions and 0 deletions
				
			
		| 
						 | 
					@ -8,6 +8,11 @@ executable('test-ringbuffer', 'test-ringbuffer.c',
 | 
				
			||||||
           dependencies : [dl_lib, pthread_lib],
 | 
					           dependencies : [dl_lib, pthread_lib],
 | 
				
			||||||
           link_with : spalib,
 | 
					           link_with : spalib,
 | 
				
			||||||
           install : false)
 | 
					           install : false)
 | 
				
			||||||
 | 
					executable('stress-ringbuffer', 'stress-ringbuffer.c',
 | 
				
			||||||
 | 
					           include_directories : [spa_inc, spa_libinc ],
 | 
				
			||||||
 | 
					           dependencies : [dl_lib, pthread_lib],
 | 
				
			||||||
 | 
					           link_with : spalib,
 | 
				
			||||||
 | 
					           install : false)
 | 
				
			||||||
executable('test-v4l2', 'test-v4l2.c',
 | 
					executable('test-v4l2', 'test-v4l2.c',
 | 
				
			||||||
           include_directories : [spa_inc, spa_libinc ],
 | 
					           include_directories : [spa_inc, spa_libinc ],
 | 
				
			||||||
           dependencies : [dl_lib, sdl_dep, pthread_lib],
 | 
					           dependencies : [dl_lib, sdl_dep, pthread_lib],
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										122
									
								
								spa/tests/stress-ringbuffer.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								spa/tests/stress-ringbuffer.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,122 @@
 | 
				
			||||||
 | 
					#define _GNU_SOURCE
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					#include <pthread.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <sched.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <spa/ringbuffer.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ARRAY_SIZE 64
 | 
				
			||||||
 | 
					#define MAX_VALUE 0x10000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SpaRingbuffer rb;
 | 
				
			||||||
 | 
					uint8_t *data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					fill_int_array (int *array, int start, int count)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  int i, j = start;
 | 
				
			||||||
 | 
					  for (i = 0; i < count; i++)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    array[i] = j;
 | 
				
			||||||
 | 
					    j = (j + 1) % MAX_VALUE;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return j;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					cmp_array (int *array1, int *array2, int count)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  int i;
 | 
				
			||||||
 | 
					  for (i = 0; i < count; i++)
 | 
				
			||||||
 | 
					    if (array1[i] != array2[i])
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      printf("%d != %d at offset %d\n", array1[i], array2[i], i);
 | 
				
			||||||
 | 
					      return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void *
 | 
				
			||||||
 | 
					reader_start (void * arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  int i = 0, a[ARRAY_SIZE], b[ARRAY_SIZE];
 | 
				
			||||||
 | 
					  unsigned long j = 0, nfailures = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  printf("reader started on cpu: %d\n", sched_getcpu());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  i = fill_int_array (a, i, ARRAY_SIZE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  while (1)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    uint32_t index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (spa_ringbuffer_get_read_index (&rb, &index) >= ARRAY_SIZE * sizeof (int))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      spa_ringbuffer_read_data (&rb, data, index & rb.mask, b, ARRAY_SIZE * sizeof (int));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (!cmp_array (a, b, ARRAY_SIZE))
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        nfailures++;
 | 
				
			||||||
 | 
					        printf("failure in chunk %lu - probability: %lu/%lu = %.3f per million\n",
 | 
				
			||||||
 | 
					               j, nfailures, j, (float) nfailures / (j + 1) * 1000000);
 | 
				
			||||||
 | 
					        i = (b[0] + ARRAY_SIZE) % MAX_VALUE;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      i = fill_int_array (a, i, ARRAY_SIZE);
 | 
				
			||||||
 | 
					      j++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      spa_ringbuffer_read_update (&rb, index + ARRAY_SIZE * sizeof (int));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void *
 | 
				
			||||||
 | 
					writer_start (void * arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  int i = 0, a[ARRAY_SIZE];
 | 
				
			||||||
 | 
					  printf("writer started on cpu: %d\n", sched_getcpu());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  i = fill_int_array (a, i, ARRAY_SIZE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  while (1)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    uint32_t index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (spa_ringbuffer_get_write_index (&rb, &index) >= ARRAY_SIZE * sizeof (int))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      spa_ringbuffer_write_data (&rb, data, index & rb.mask, a, ARRAY_SIZE * sizeof (int));
 | 
				
			||||||
 | 
					      spa_ringbuffer_write_update (&rb, index + ARRAY_SIZE * sizeof (int));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      i = fill_int_array (a, i, ARRAY_SIZE);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(int argc, char *argv[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  int size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  printf("starting ringbuffer stress test\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  sscanf(argv[1], "%d", &size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  printf("buffer size (bytes): %d\n", size);
 | 
				
			||||||
 | 
					  printf("array size (bytes): %ld\n", sizeof(int) * ARRAY_SIZE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  spa_ringbuffer_init (&rb, size);
 | 
				
			||||||
 | 
					  data = malloc (size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pthread_t reader_thread, writer_thread;
 | 
				
			||||||
 | 
					  pthread_create (&reader_thread, NULL, reader_start, NULL);
 | 
				
			||||||
 | 
					  pthread_create (&writer_thread, NULL, writer_start, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  while (1)
 | 
				
			||||||
 | 
					    sleep(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue