~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
JACK/libjack/driver.c


** Warning: Cannot open xref database.

1 /* -*- mode: c; c-file-style: "linux"; -*- */ 2 /* 3 Copyright (C) 2001-2003 Paul Davis 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU Lesser General Public License as published by 7 the Free Software Foundation; either version 2.1 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public License 16 along with this program; if not, write to the Free Software 17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 19 $Id: driver.c,v 1.13 2003/12/10 06:52:17 joq Exp $ 20 */ 21 22 #include <stdio.h> 23 #include <string.h> 24 #include <stdarg.h> 25 #include <stdlib.h> 26 #include <stdio.h> 27 #include <sys/mman.h> 28 #include <errno.h> 29 30 #include <config.h> 31 32 #include <jack/driver.h> 33 #include <jack/internal.h> 34 #include <jack/engine.h> 35 36 static int dummy_attach (jack_driver_t *drv, jack_engine_t *eng) { return 0; } 37 static int dummy_detach (jack_driver_t *drv, jack_engine_t *eng) { return 0; } 38 static int dummy_write (jack_driver_t *drv, 39 jack_nframes_t nframes) { return 0; } 40 static int dummy_read (jack_driver_t *drv, jack_nframes_t nframes) { return 0; } 41 static int dummy_null_cycle (jack_driver_t *drv, 42 jack_nframes_t nframes) { return 0; } 43 static int dummy_bufsize (jack_driver_t *drv, 44 jack_nframes_t nframes) {return 0;} 45 static int dummy_stop (jack_driver_t *drv) { return 0; } 46 static int dummy_start (jack_driver_t *drv) { return 0; } 47 48 void 49 jack_driver_init (jack_driver_t *driver) 50 { 51 memset (driver, 0, sizeof (*driver)); 52 53 driver->attach = dummy_attach; 54 driver->detach = dummy_detach; 55 driver->write = dummy_write; 56 driver->read = dummy_read; 57 driver->null_cycle = dummy_null_cycle; 58 driver->bufsize = dummy_bufsize; 59 driver->start = dummy_start; 60 driver->stop = dummy_stop; 61 } 62 63 64 65 /**************************** 66 *** Non-Threaded Drivers *** 67 ****************************/ 68 69 static int dummy_nt_run_cycle (jack_driver_nt_t *drv) { return 0; } 70 static int dummy_nt_attach (jack_driver_nt_t *drv) { return 0; } 71 static int dummy_nt_detach (jack_driver_nt_t *drv) { return 0; } 72 73 74 /* 75 * These are used in driver->nt_run for controlling whether or not 76 * driver->engine->driver_exit() gets called (EXIT = call it, PAUSE = don't) 77 */ 78 #define DRIVER_NT_RUN 0 79 #define DRIVER_NT_EXIT 1 80 #define DRIVER_NT_PAUSE 2 81 82 static int 83 jack_driver_nt_attach (jack_driver_nt_t * driver, jack_engine_t * engine) 84 { 85 driver->engine = engine; 86 return driver->nt_attach (driver); 87 } 88 89 static int 90 jack_driver_nt_detach (jack_driver_nt_t * driver, jack_engine_t * engine) 91 { 92 int ret; 93 94 ret = driver->nt_detach (driver); 95 driver->engine = NULL; 96 97 return ret; 98 } 99 100 static int 101 jack_driver_nt_become_real_time (jack_driver_nt_t* driver) 102 { 103 if (jack_acquire_real_time_scheduling (driver->nt_thread, 104 driver->engine->rtpriority)) { 105 return -1; 106 } 107 108 if (mlockall (MCL_CURRENT | MCL_FUTURE) != 0) { 109 jack_error ("cannot lock down memory for RT thread (%s)", 110 strerror (errno)); 111 #ifdef ENSURE_MLOCK 112 return -1; 113 #endif /* ENSURE_MLOCK */ 114 } 115 116 return 0; 117 } 118 119 120 static void * 121 jack_driver_nt_thread (void * arg) 122 { 123 jack_driver_nt_t * driver = (jack_driver_nt_t *) arg; 124 int rc = 0; 125 int run; 126 127 /* This thread may start running before pthread_create() 128 * actually stores the driver->nt_thread value. It's safer to 129 * store it here as well. */ 130 driver->nt_thread = pthread_self(); 131 132 if (driver->engine->control->real_time) 133 jack_driver_nt_become_real_time (driver); 134 135 pthread_mutex_lock (&driver->nt_run_lock); 136 137 while ( (run = driver->nt_run) == DRIVER_NT_RUN) { 138 pthread_mutex_unlock (&driver->nt_run_lock); 139 140 rc = driver->nt_run_cycle (driver); 141 if (rc) { 142 jack_error ("DRIVER NT: could not run driver cycle"); 143 goto out; 144 } 145 146 pthread_mutex_lock (&driver->nt_run_lock); 147 } 148 149 pthread_mutex_unlock (&driver->nt_run_lock); 150 151 out: 152 if (rc) { 153 driver->engine->driver_exit (driver->engine); 154 } 155 pthread_exit (NULL); 156 } 157 158 static int 159 jack_driver_nt_start (jack_driver_nt_t * driver) 160 { 161 int err; 162 163 err = driver->nt_start (driver); 164 if (err) { 165 jack_error ("DRIVER NT: could not start driver"); 166 return err; 167 } 168 169 driver->nt_run = DRIVER_NT_RUN; 170 171 err = pthread_create (&driver->nt_thread, NULL, 172 jack_driver_nt_thread, driver); 173 if (err) { 174 jack_error ("DRIVER NT: could not start driver thread!"); 175 driver->nt_stop (driver); 176 return err; 177 } 178 179 return 0; 180 } 181 182 static int 183 jack_driver_nt_do_stop (jack_driver_nt_t * driver, int run) 184 { 185 int err; 186 187 pthread_mutex_lock (&driver->nt_run_lock); 188 driver->nt_run = run; 189 pthread_mutex_unlock (&driver->nt_run_lock); 190 191 err = pthread_join (driver->nt_thread, NULL); 192 if (err) { 193 jack_error ("DRIVER NT: error waiting for driver thread: %s", 194 strerror (err)); 195 return err; 196 } 197 198 err = driver->nt_stop (driver); 199 if (err) { 200 jack_error ("DRIVER NT: error stopping driver"); 201 return err; 202 } 203 204 return 0; 205 } 206 207 static int 208 jack_driver_nt_stop (jack_driver_nt_t * driver) 209 { 210 return jack_driver_nt_do_stop (driver, DRIVER_NT_EXIT); 211 } 212 213 static int 214 jack_driver_nt_bufsize (jack_driver_nt_t * driver, jack_nframes_t nframes) 215 { 216 int err; 217 int ret; 218 219 err = jack_driver_nt_do_stop (driver, DRIVER_NT_PAUSE); 220 if (err) { 221 jack_error ("DRIVER NT: could not stop driver to change buffer size"); 222 driver->engine->driver_exit (driver->engine); 223 return err; 224 } 225 226 ret = driver->nt_bufsize (driver, nframes); 227 228 err = jack_driver_nt_start (driver); 229 if (err) { 230 jack_error ("DRIVER NT: could not restart driver during buffer size change"); 231 driver->engine->driver_exit (driver->engine); 232 return err; 233 } 234 235 return ret; 236 } 237 238 void 239 jack_driver_nt_init (jack_driver_nt_t * driver) 240 { 241 memset (driver, 0, sizeof (*driver)); 242 243 jack_driver_init ((jack_driver_t *) driver); 244 245 driver->attach = (JackDriverAttachFunction) jack_driver_nt_attach; 246 driver->detach = (JackDriverDetachFunction) jack_driver_nt_detach; 247 driver->bufsize = (JackDriverBufSizeFunction) jack_driver_nt_bufsize; 248 driver->stop = (JackDriverStartFunction) jack_driver_nt_stop; 249 driver->start = (JackDriverStopFunction) jack_driver_nt_start; 250 251 driver->nt_bufsize = (JackDriverNTBufSizeFunction) dummy_bufsize; 252 driver->nt_start = (JackDriverNTStartFunction) dummy_start; 253 driver->nt_stop = (JackDriverNTStopFunction) dummy_stop; 254 driver->nt_attach = dummy_nt_attach; 255 driver->nt_detach = dummy_nt_detach; 256 driver->nt_run_cycle = dummy_nt_run_cycle; 257 258 259 pthread_mutex_init (&driver->nt_run_lock, NULL); 260 } 261 262 void 263 jack_driver_nt_finish (jack_driver_nt_t * driver) 264 { 265 pthread_mutex_destroy (&driver->nt_run_lock); 266 } 267

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.