README: Add supplemental information for M-Audio BeBoB devices
[ffado.git] / libffado / tests / test-shm.cpp
blobb983e9836cdfebe4f66373a112e0c09b1e29864b
1 /*
2 * Copyright (C) 2005-2008 by Pieter Palmers
4 * This file is part of FFADO
5 * FFADO = Free Firewire (pro-)audio drivers for linux
7 * FFADO is based upon FreeBoB
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.
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.
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/>.
24 #include "debugmodule/debugmodule.h"
26 #include "libutil/PosixSharedMemory.h"
28 #include <argp.h>
29 #include <stdlib.h>
30 #include <iostream>
31 #include <signal.h>
32 #include <unistd.h>
34 using namespace Util;
36 DECLARE_GLOBAL_DEBUG_MODULE;
38 #define MAX_ARGS 2
40 int run=1;
41 int lastsig=-1;
42 static void sighandler (int sig)
44 run = 0;
47 ////////////////////////////////////////////////
48 // arg parsing
49 ////////////////////////////////////////////////
50 const char *argp_program_version = "test-shm 0.1";
51 const char *argp_program_bug_address = "<ffado-devel@lists.sf.net>";
52 static char doc[] = "test-avccmd -- test program to test the shared memory class.";
53 static char args_doc[] = "DIRECTION";
54 static struct argp_option options[] = {
55 {"verbose", 'v', "level", 0, "Produce verbose output" },
56 { 0 }
59 struct arguments
61 arguments()
62 : nargs ( 0 )
63 , verbose( false )
65 args[0] = 0;
68 char* args[MAX_ARGS];
69 int nargs;
70 long int verbose;
71 } arguments;
73 // Parse a single option.
74 static error_t
75 parse_opt( int key, char* arg, struct argp_state* state )
77 // Get the input argument from `argp_parse', which we
78 // know is a pointer to our arguments structure.
79 struct arguments* arguments = ( struct arguments* ) state->input;
81 char* tail;
82 errno = 0;
83 switch (key) {
84 case 'v':
85 if (arg) {
86 arguments->verbose = strtol( arg, &tail, 0 );
87 if ( errno ) {
88 fprintf( stderr, "Could not parse 'verbose' argument\n" );
89 return ARGP_ERR_UNKNOWN;
92 break;
93 case ARGP_KEY_ARG:
94 if (state->arg_num >= MAX_ARGS) {
95 // Too many arguments.
96 argp_usage (state);
98 arguments->args[state->arg_num] = arg;
99 arguments->nargs++;
100 break;
101 case ARGP_KEY_END:
102 if(arguments->nargs <= 0) {
103 printMessage("not enough arguments\n");
104 return -1;
106 break;
107 default:
108 return ARGP_ERR_UNKNOWN;
110 return 0;
113 static struct argp argp = { options, parse_opt, args_doc, doc };
115 ///////////////////////////
116 // main
117 //////////////////////////
119 main(int argc, char **argv)
121 signal (SIGINT, sighandler);
122 signal (SIGPIPE, sighandler);
124 // arg parsing
125 if ( argp_parse ( &argp, argc, argv, 0, 0, &arguments ) ) {
126 fprintf( stderr, "Could not parse command line\n" );
127 exit(-1);
130 setDebugLevel(arguments.verbose);
132 errno = 0;
133 char* tail;
134 long int direction = strtol( arguments.args[0], &tail, 0 );
135 if ( errno ) {
136 fprintf( stderr, "Could not parse direction argument\n" );
137 exit(-1);
140 printMessage("Testing shared memory direction %ld\n", direction);
142 PosixSharedMemory s = PosixSharedMemory("testseg", 1024);
143 s.setVerboseLevel(arguments.verbose);
145 if(direction == 0) {
146 if(!s.Create(PosixSharedMemory::eD_ReadWrite)) {
147 debugError("Could not create segment\n");
148 exit(-1);
150 } else {
151 if(!s.Open(PosixSharedMemory::eD_ReadOnly)) {
152 debugError("Could not open segment\n");
153 exit(-1);
157 if(!s.LockInMemory(true)) {
158 debugError("Could not memlock segment\n");
161 int offset=0;
162 int len = 64;
163 char buff[len];
165 int cnt = 0;
166 run=1;
167 long int time_to_sleep = 1000*1000;
168 while(run) {
169 if(direction == 0) {
170 snprintf(buff, len, "test %d", cnt++);
171 printMessage("writing '%s'...\n", buff);
172 if(s.Write(offset, buff, len) != PosixSharedMemory::eR_OK) {
173 debugError("Could not write to segment\n");
174 goto out_err;
176 usleep(time_to_sleep);
177 } else {
178 printMessage("reading...\n");
179 if(s.Read(offset, buff, len) != PosixSharedMemory::eR_OK) {
180 debugError("Could not receive from queue\n");
181 goto out_err;
183 buff[len-1]=0;
184 printMessage(" read: '%s'\n", buff);
185 usleep(time_to_sleep * 110/100);
189 if(!s.LockInMemory(false)) {
190 debugError("Could not mem-unlock segment\n");
193 return 0;
195 out_err:
196 if(!s.LockInMemory(false)) {
197 debugError("Could not mem-unlock segment\n");
199 return -1;