git-svn-id: svn+ssh://jackaudio.org/trunk/jack@174 0c269be4-1314-0410-8aa9-9f06e86f4224tags/0.109.0
| @@ -849,6 +849,7 @@ alsa_driver_wait (alsa_driver_t *driver, int extra_fd, int *status, float *delay | |||
| } | |||
| driver->poll_last = poll_ret; | |||
| driver->poll_next = poll_ret + (unsigned long long) floor ((driver->period_usecs * driver->cpu_mhz)); | |||
| driver->engine->control->time.cycles = get_cycles(); | |||
| } | |||
| /* check to see if it was the extra FD that caused us to return from poll | |||
| @@ -875,12 +876,6 @@ alsa_driver_wait (alsa_driver_t *driver, int extra_fd, int *status, float *delay | |||
| return (driver->pfd[nfds-1].revents == POLLIN) ? 0 : -1; | |||
| } | |||
| if (driver->engine) { | |||
| struct timeval tv; | |||
| gettimeofday (&tv, NULL); | |||
| driver->engine->control->time.microseconds = tv.tv_sec * 1000000 + tv.tv_usec; | |||
| } | |||
| p_timed_out = 0; | |||
| if (need_playback) { | |||
| @@ -77,6 +77,7 @@ struct _jack_client { | |||
| void *on_shutdown_arg; | |||
| char thread_ok : 1; | |||
| char first_active : 1; | |||
| float cpu_mhz; | |||
| }; | |||
| #define event_fd pollfd[0].fd | |||
| @@ -123,6 +124,7 @@ jack_client_alloc () | |||
| client->thread_ok = FALSE; | |||
| client->first_active = TRUE; | |||
| client->on_shutdown = NULL; | |||
| client->cpu_mhz = (float) jack_get_mhz (); | |||
| return client; | |||
| } | |||
| @@ -1560,18 +1562,52 @@ jack_get_ports (jack_client_t *client, | |||
| return matching_ports; | |||
| } | |||
| static inline void | |||
| jack_read_frame_time (const jack_client_t *client, jack_frame_timer_t *copy) | |||
| { | |||
| int tries = 0; | |||
| do { | |||
| /* throttle the busy wait if we don't get | |||
| the answer very quickly. | |||
| */ | |||
| if (tries > 10) { | |||
| usleep (20); | |||
| tries = 0; | |||
| } | |||
| *copy = client->engine->frame_timer; | |||
| tries++; | |||
| } while (copy->guard1 != copy->guard2); | |||
| } | |||
| nframes_t | |||
| jack_frames_since_cycle_start (jack_client_t *client) | |||
| jack_frames_since_cycle_start (const jack_client_t *client) | |||
| { | |||
| struct timeval now; | |||
| float usecs; | |||
| gettimeofday (&now, NULL); | |||
| usecs = ((now.tv_sec * 1000000) + now.tv_usec) - client->engine->time.microseconds; | |||
| usecs = (float) (get_cycles() - client->engine->time.cycles) / client->cpu_mhz; | |||
| return (nframes_t) floor ((((float) client->engine->time.frame_rate) / 1000000.0f) * usecs); | |||
| } | |||
| nframes_t | |||
| jack_frame_time (const jack_client_t *client) | |||
| { | |||
| jack_frame_timer_t current; | |||
| float usecs; | |||
| nframes_t elapsed; | |||
| jack_read_frame_time (client, ¤t); | |||
| usecs = (float) (get_cycles() - current.stamp) / client->cpu_mhz; | |||
| elapsed = (nframes_t) floor ((((float) client->engine->time.frame_rate) / 1000000.0f) * usecs); | |||
| return current.frames + elapsed; | |||
| } | |||
| int | |||
| jack_port_lock (jack_client_t *client, jack_port_t *port) | |||
| { | |||
| @@ -1796,3 +1832,6 @@ jack_cpu_load (jack_client_t *client) | |||
| { | |||
| return client->engine->cpu_load; | |||
| } | |||
| @@ -4,8 +4,8 @@ AC_INIT(client.c) | |||
| AC_CONFIG_AUX_DIR(.) | |||
| JACK_MAJOR_VERSION=0 | |||
| JACK_MINOR_VERSION=26 | |||
| JACK_MICRO_VERSION=3 | |||
| JACK_MINOR_VERSION=27 | |||
| JACK_MICRO_VERSION=0 | |||
| BETA= | |||
| @@ -1244,6 +1244,7 @@ jack_engine_new (int realtime, int rtpriority, int verbose) | |||
| engine->control->buffer_size = 0; | |||
| engine->control->time.frame_rate = 0; | |||
| engine->control->time.frame = 0; | |||
| engine->control->in_process = 0; | |||
| snprintf (engine->fifo_prefix, sizeof (engine->fifo_prefix), "%s/jack-ack-fifo-%d", jack_temp_dir, getpid()); | |||
| @@ -1337,6 +1338,23 @@ jack_engine_notify_clients_about_delay (jack_engine_t *engine) | |||
| jack_unlock_graph (engine); | |||
| } | |||
| static inline void | |||
| jack_inc_frame_time (jack_engine_t *engine, nframes_t amount) | |||
| { | |||
| jack_frame_timer_t *time = &engine->control->frame_timer; | |||
| // atomic_inc (&time->guard1, 1); | |||
| // really need a memory barrier here | |||
| time->guard1++; | |||
| time->frames += amount; | |||
| time->stamp = get_cycles (); | |||
| // atomic_inc (&time->guard2, 1); | |||
| // might need a memory barrier here | |||
| time->guard2++; | |||
| } | |||
| static void * | |||
| jack_main_thread (void *arg) | |||
| @@ -1344,7 +1362,8 @@ jack_main_thread (void *arg) | |||
| jack_engine_t *engine = (jack_engine_t *) arg; | |||
| jack_driver_t *driver = engine->driver; | |||
| int consecutive_excessive_delays; | |||
| unsigned long long cycle_start, cycle_end; | |||
| unsigned long long cycle_end; | |||
| nframes_t nframes; | |||
| if (engine->control->real_time) { | |||
| @@ -1368,15 +1387,15 @@ jack_main_thread (void *arg) | |||
| consecutive_excessive_delays = 0; | |||
| engine->watchdog_check = 1; | |||
| nframes = 0; | |||
| while (1) { | |||
| int status; | |||
| nframes_t nframes; | |||
| float delayed_usecs; | |||
| nframes = driver->wait (driver, -1, &status, &delayed_usecs); | |||
| cycle_start = get_cycles(); | |||
| jack_inc_frame_time (engine, nframes); | |||
| engine->watchdog_check = 1; | |||
| @@ -1434,9 +1453,10 @@ jack_main_thread (void *arg) | |||
| cycle_end = get_cycles (); | |||
| /* store the execution time for this this part of the graph */ | |||
| /* store the execution time for later averaging */ | |||
| engine->rolling_client_usecs[engine->rolling_client_usecs_index++] = (float) (cycle_end - cycle_start) / engine->cpu_mhz; | |||
| engine->rolling_client_usecs[engine->rolling_client_usecs_index++] = | |||
| (float) (cycle_end - engine->control->time.cycles) / engine->cpu_mhz; | |||
| if (engine->rolling_client_usecs_index >= JACK_ENGINE_ROLLING_COUNT) { | |||
| engine->rolling_client_usecs_index = 0; | |||
| @@ -2815,3 +2835,4 @@ jack_set_asio_mode (jack_engine_t *engine, int yn) | |||
| { | |||
| engine->asio_mode = yn; | |||
| } | |||
| @@ -205,7 +205,6 @@ hammerfall_release (jack_hardware_t *hw) | |||
| static void * | |||
| hammerfall_monitor_controls (void *arg) | |||
| { | |||
| jack_hardware_t *hw = (jack_hardware_t *) arg; | |||
| hammerfall_t *h = (hammerfall_t *) hw->private; | |||
| @@ -29,6 +29,7 @@ | |||
| #include <sys/time.h> | |||
| #include <pthread.h> | |||
| #include <glib.h> | |||
| #include <asm/timex.h> | |||
| #include <jack/jack.h> | |||
| #include <jack/types.h> | |||
| @@ -51,7 +52,7 @@ typedef struct _time_info | |||
| { | |||
| nframes_t frame; | |||
| nframes_t frame_rate; | |||
| unsigned long microseconds; | |||
| cycles_t cycles; | |||
| jack_transport_state_t transport_state; | |||
| nframes_t loop_start; | |||
| nframes_t loop_end; | |||
| @@ -73,9 +74,19 @@ typedef struct _time_info | |||
| } jack_time_info_t; | |||
| typedef struct { | |||
| volatile unsigned long long guard1; | |||
| volatile nframes_t frames; | |||
| volatile cycles_t stamp; | |||
| volatile unsigned long long guard2; | |||
| } jack_frame_timer_t; | |||
| typedef struct { | |||
| jack_time_info_t time; | |||
| jack_frame_timer_t frame_timer; | |||
| int in_process; | |||
| nframes_t frames_at_cycle_start; | |||
| pid_t engine_pid; | |||
| unsigned long buffer_size; | |||
| char real_time; | |||
| @@ -515,7 +515,16 @@ void jack_update_time (jack_client_t *, nframes_t); | |||
| * callbacks of all its clients. | |||
| */ | |||
| nframes_t jack_frames_since_cycle_start (jack_client_t *); | |||
| nframes_t jack_frames_since_cycle_start (const jack_client_t *); | |||
| /** | |||
| * Return an estimate of the current time in frames. It is a running | |||
| * counter - no significance should be attached to the return | |||
| * value. it should be used to compute the difference between | |||
| * a previously returned value. | |||
| */ | |||
| nframes_t jack_frame_time (const jack_client_t *); | |||
| /** | |||
| * This returns the current CPU load estimated by JACK | |||
| @@ -232,7 +232,6 @@ static void | |||
| jack_main (int argc, char **argv) | |||
| { | |||
| int sig; | |||
| int err; | |||
| pthread_t waiter_thread; | |||
| waiter_arg_t warg; | |||
| @@ -273,8 +272,12 @@ jack_main (int argc, char **argv) | |||
| sigdelset (&signals, SIGINT); | |||
| } | |||
| if (verbose) { | |||
| fprintf (stderr, "%d waiting for signals\n", getpid()); | |||
| } | |||
| while(1) { | |||
| err = sigwait (&signals, &sig); | |||
| sigwait (&signals, &sig); | |||
| printf ("jack main caught signal %d\n", sig); | |||