root/trunk/libffado/tests/test-ipcringbuffer.cpp

Revision 2088, 6.1 kB (checked in by jwoithe, 12 years ago)

More fixes for compilation under gcc 4.7. Patch supplied by "oget". Fixes reopened ticket #344.

Line 
1 /*
2  * Copyright (C) 2005-2008 by Pieter Palmers
3  *
4  * This file is part of FFADO
5  * FFADO = Free Firewire (pro-)audio drivers for linux
6  *
7  * FFADO is based upon FreeBoB
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 2 of the License, or
12  * (at your option) version 3 of the License.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  */
23
24 #include "debugmodule/debugmodule.h"
25
26 #include "libutil/IpcRingBuffer.h"
27 #include "libutil/SystemTimeSource.h"
28
29 #include <argp.h>
30 #include <stdlib.h>
31 #include <iostream>
32 #include <signal.h>
33 #include <unistd.h>
34
35 using namespace Util;
36
37 DECLARE_GLOBAL_DEBUG_MODULE;
38
39 #define MAX_ARGS 2
40
41 int run=1;
42 int lastsig=-1;
43 static void sighandler (int sig)
44 {
45     run = 0;
46 }
47
48 ////////////////////////////////////////////////
49 // arg parsing
50 ////////////////////////////////////////////////
51 const char *argp_program_version = "test-ipcringbuffer 0.1";
52 const char *argp_program_bug_address = "<ffado-devel@lists.sf.net>";
53 static char doc[] = "test-avccmd -- test program to test the ipc ringbuffer class.";
54 static char args_doc[] = "DIRECTION";
55 static struct argp_option options[] = {
56     {"verbose",  'v', "level",    0,  "Produce verbose output" },
57    { 0 }
58 };
59
60 struct arguments
61 {
62     arguments()
63         : nargs ( 0 )
64         , verbose( false )
65         {
66             args[0] = 0;
67         }
68
69     char* args[MAX_ARGS];
70     int   nargs;
71     long int verbose;
72 } arguments;
73
74 // Parse a single option.
75 static error_t
76 parse_opt( int key, char* arg, struct argp_state* state )
77 {
78     // Get the input argument from `argp_parse', which we
79     // know is a pointer to our arguments structure.
80     struct arguments* arguments = ( struct arguments* ) state->input;
81
82     char* tail;
83     errno = 0;
84     switch (key) {
85     case 'v':
86         if (arg) {
87             arguments->verbose = strtol( arg, &tail, 0 );
88             if ( errno ) {
89                 fprintf( stderr,  "Could not parse 'verbose' argument\n" );
90                 return ARGP_ERR_UNKNOWN;
91             }
92         }
93         break;
94     case ARGP_KEY_ARG:
95         if (state->arg_num >= MAX_ARGS) {
96             // Too many arguments.
97             argp_usage (state);
98         }
99         arguments->args[state->arg_num] = arg;
100         arguments->nargs++;
101         break;
102     case ARGP_KEY_END:
103         if(arguments->nargs <= 0) {
104             printMessage("not enough arguments\n");
105             return -1;
106         }
107         break;
108     default:
109         return ARGP_ERR_UNKNOWN;
110     }
111     return 0;
112 }
113
114 static struct argp argp = { options, parse_opt, args_doc, doc };
115
116 ///////////////////////////
117 // main
118 //////////////////////////
119 int
120 main(int argc, char **argv)
121 {
122     signal (SIGINT, sighandler);
123     signal (SIGPIPE, sighandler);
124
125     // arg parsing
126     if ( argp_parse ( &argp, argc, argv, 0, 0, &arguments ) ) {
127         fprintf( stderr, "Could not parse command line\n" );
128         exit(-1);
129     }
130
131     setDebugLevel(arguments.verbose);
132
133     errno = 0;
134     char* tail;
135     long int direction = strtol( arguments.args[0], &tail, 0 );
136     if ( errno ) {
137         fprintf( stderr,  "Could not parse direction argument\n" );
138         exit(-1);
139     }
140
141     printMessage("Testing shared memory direction %ld\n", direction);
142
143     #define TEST_SAMPLERATE 44100
144     #define BUFF_SIZE 64
145     #define NB_BUFFERS 4
146     IpcRingBuffer* b = NULL;
147     if(direction == 0) {
148         b = new IpcRingBuffer("testbuff",
149                               IpcRingBuffer::eBT_Master,
150                               IpcRingBuffer::eD_Outward,
151                               IpcRingBuffer::eB_Blocking,
152                               NB_BUFFERS, BUFF_SIZE);
153         if(b == NULL) {
154             debugError("Could not create master\n");
155             exit(-1);
156         }
157     } else {
158         b = new IpcRingBuffer("testbuff",
159                               IpcRingBuffer::eBT_Master,
160                               IpcRingBuffer::eD_Inward,
161                               IpcRingBuffer::eB_Blocking,
162                               NB_BUFFERS, BUFF_SIZE);
163         if(b == NULL) {
164             debugError("Could not create master\n");
165             exit(-1);
166         }
167     }
168
169     b->setVerboseLevel(arguments.verbose);
170
171     char buff[BUFF_SIZE];
172     int cnt = 0;
173     long int time_to_sleep = 1000*1000*BUFF_SIZE/TEST_SAMPLERATE;
174
175     if(!b->init()) {
176         debugError("Could not init buffer\n");
177         goto out_err;
178     }
179
180     run=1;
181     while(run) {
182         if(direction == 0) {
183             snprintf(buff, BUFF_SIZE, "test %d", cnt);
184             if(cnt%1000==0) {
185                 printMessage("writing '%s'...\n", buff);
186             }
187             IpcRingBuffer::eResult res = b->Write(buff);
188             if(res != IpcRingBuffer::eR_OK && res != IpcRingBuffer::eR_Again) {
189                 debugError("Could not write to segment\n");
190                 goto out_err;
191             }
192             if(res == IpcRingBuffer::eR_Again) {
193                 printMessage(" Try again on %d...\n", cnt);
194             } else {
195                 cnt++;
196             }
197             usleep(time_to_sleep);
198         } else {
199             if(cnt%1000==0) {
200                 printMessage("reading...\n");
201             }
202
203             IpcRingBuffer::eResult res = b->Read(buff);
204             if(res != IpcRingBuffer::eR_OK && res != IpcRingBuffer::eR_Again) {
205                 debugError("Could not receive from queue\n");
206                 goto out_err;
207             }
208             if(cnt%1000==0) {
209                 buff[BUFF_SIZE-1]=0;
210                 printMessage(" read: '%s'\n", buff);
211             }
212             if(res == IpcRingBuffer::eR_Again) {
213                 printMessage(" Try again on %d...\n", cnt);
214             } else {
215                 cnt++;
216             }
217         }
218     }
219
220     delete b;
221     return 0;
222
223 out_err:
224     delete b;
225     return -1;
226 }
227
Note: See TracBrowser for help on using the browser.