X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=libs%2Fardour%2Fsession_butler.cc;h=4f8f244c223c9c5c76fb5e67aefe36565f749ce6;hb=33da74c8e353ac56194956cae8e2b7d74ec1a1b0;hp=ec5de23caffbc537f74fb58719a0b15e614a6a92;hpb=449aab3c465bbbf66d221fac3d7ea559f1720357;p=ardour.git diff --git a/libs/ardour/session_butler.cc b/libs/ardour/session_butler.cc index ec5de23caf..4f8f244c22 100644 --- a/libs/ardour/session_butler.cc +++ b/libs/ardour/session_butler.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 1999-2002 Paul Davis + Copyright (C) 1999-2002 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -27,16 +27,18 @@ #include -#include -#include -#include +#include "pbd/error.h" +#include "pbd/pthread_utils.h" +#include "pbd/stacktrace.h" -#include -#include -#include -#include -#include -#include +#include "ardour/audio_diskstream.h" +#include "ardour/audioengine.h" +#include "ardour/configuration.h" +#include "ardour/crossfade.h" +#include "ardour/io.h" +#include "ardour/midi_diskstream.h" +#include "ardour/session.h" +#include "ardour/timestamps.h" #include "i18n.h" @@ -62,7 +64,7 @@ static inline uint32_t next_power_of_two (uint32_t n) } /*--------------------------------------------------------------------------- - BUTLER THREAD + BUTLER THREAD ---------------------------------------------------------------------------*/ int @@ -70,13 +72,14 @@ Session::start_butler_thread () { /* size is in Samples, not bytes */ audio_dstream_buffer_size = (uint32_t) floor (Config->get_audio_track_buffer_seconds() * (float) frame_rate()); - + /* size is in bytes * XXX: Jack needs to tell us the MIDI buffer size * (i.e. how many MIDI bytes we might see in a cycle) */ midi_dstream_buffer_size = (uint32_t) floor (Config->get_midi_track_buffer_seconds() * (float)frame_rate()); - + MidiDiskstream::set_readahead_frames ((nframes_t) (Config->get_midi_readahead() * (float) frame_rate())); + Crossfade::set_buffer_size (audio_dstream_buffer_size); butler_should_run = false; @@ -160,7 +163,7 @@ Session::wait_till_butler_finished () void * Session::_butler_thread_work (void* arg) { - PBD::ThreadCreated (pthread_self(), X_("Butler")); + PBD::notify_gui_about_thread_creation (pthread_self(), X_("Butler")); return ((Session *) arg)->butler_thread_work (); return 0; } @@ -171,7 +174,8 @@ Session::butler_thread_work () uint32_t err = 0; int32_t bytes; bool compute_io; - struct timeval begin, end; + microseconds_t begin, end; + struct pollfd pfd[1]; bool disk_work_outstanding = false; DiskstreamList::iterator i; @@ -179,13 +183,13 @@ Session::butler_thread_work () while (true) { pfd[0].fd = butler_request_pipe[0]; pfd[0].events = POLLIN|POLLERR|POLLHUP; - + if (poll (pfd, 1, (disk_work_outstanding ? 0 : -1)) < 0) { - + if (errno == EINTR) { continue; } - + error << string_compose (_("poll on butler request pipe failed (%1)"), strerror (errno)) << endmsg; @@ -196,39 +200,39 @@ Session::butler_thread_work () error << string_compose (_("Error on butler thread request pipe: fd=%1 err=%2"), pfd[0].fd, pfd[0].revents) << endmsg; break; } - + if (pfd[0].revents & POLLIN) { char req; - + /* empty the pipe of all current requests */ - + while (1) { size_t nread = ::read (butler_request_pipe[0], &req, sizeof (req)); if (nread == 1) { - + switch ((ButlerRequest::Type) req) { - + case ButlerRequest::Wake: break; case ButlerRequest::Run: butler_should_run = true; break; - + case ButlerRequest::Pause: butler_should_run = false; break; - + case ButlerRequest::Quit: pthread_exit_pbd (0); /*NOTREACHED*/ break; - + default: break; } - + } else if (nread == 0) { break; } else if (errno == EAGAIN) { @@ -248,7 +252,7 @@ Session::butler_thread_work () bytes = 0; compute_io = true; - gettimeofday (&begin, 0); + begin = get_microseconds(); boost::shared_ptr dsl = diskstreams.reader (); @@ -262,8 +266,8 @@ Session::butler_thread_work () /* don't read inactive tracks */ - IO* io = ds->io(); - + boost::shared_ptr io = ds->io(); + if (io && !io->active()) { continue; } @@ -276,7 +280,7 @@ Session::butler_thread_work () bytes += ds->read_data_count(); disk_work_outstanding = true; break; - + default: compute_io = false; error << string_compose(_("Butler read ahead failure on dstream %1"), (*i)->name()) << endmsg; @@ -289,31 +293,30 @@ Session::butler_thread_work () /* we didn't get to all the streams */ disk_work_outstanding = true; } - + if (!err && transport_work_requested()) { continue; } if (compute_io) { - gettimeofday (&end, 0); - - double b = begin.tv_sec + (begin.tv_usec/1000000.0); - double e = end.tv_sec + (end.tv_usec / 1000000.0); - - _read_data_rate = bytes / (e - b); + end = get_microseconds(); + if(end-begin > 0) { + _read_data_rate = (float) bytes / (float) (end - begin); + } else { _read_data_rate = 0; // infinity better + } } bytes = 0; compute_io = true; - gettimeofday (&begin, 0); + begin = get_microseconds(); for (i = dsl->begin(); !transport_work_requested() && butler_should_run && i != dsl->end(); ++i) { // cerr << "write behind for " << (*i)->name () << endl; /* note that we still try to flush diskstreams attached to inactive routes */ - - switch ((*i)->do_flush (Session::ButlerContext)) { + + switch ((*i)->do_flush (ButlerContext)) { case 0: bytes += (*i)->write_data_count(); break; @@ -321,12 +324,12 @@ Session::butler_thread_work () bytes += (*i)->write_data_count(); disk_work_outstanding = true; break; - + default: err++; compute_io = false; error << string_compose(_("Butler write-behind failure on dstream %1"), (*i)->name()) << endmsg; - /* don't break - try to flush all streams in case they + /* don't break - try to flush all streams in case they are split across disks. */ } @@ -343,20 +346,21 @@ Session::butler_thread_work () /* we didn't get to all the streams */ disk_work_outstanding = true; } - + if (!err && transport_work_requested()) { continue; } if (compute_io) { - gettimeofday (&end, 0); - - double b = begin.tv_sec + (begin.tv_usec/1000000.0); - double e = end.tv_sec + (end.tv_usec / 1000000.0); - - _write_data_rate = bytes / (e - b); + // there are no apparent users for this calculation? + end = get_microseconds(); + if(end-begin > 0) { + _write_data_rate = (float) bytes / (float) (end - begin); + } else { + _write_data_rate = 0; // Well, infinity would be better + } } - + if (!disk_work_outstanding) { refresh_disk_space (); } @@ -421,7 +425,7 @@ Session::read_data_rate () const /* disk i/o in excess of 10000MB/sec indicate the buffer cache in action. ignore it. */ - return _read_data_rate > 10485760000.0f ? 0.0f : _read_data_rate; + return _read_data_rate > 10485.7600000f ? 0.0f : _read_data_rate; } float @@ -430,7 +434,7 @@ Session::write_data_rate () const /* disk i/o in excess of 10000MB/sec indicate the buffer cache in action. ignore it. */ - return _write_data_rate > 10485760000.0f ? 0.0f : _write_data_rate; + return _write_data_rate > 10485.7600000f ? 0.0f : _write_data_rate; } uint32_t