John Patrick Poet wrote:


As Isaac suggested, this patch moves the fdatasync(fd) call to it's own thread. The means that the ThreadedFileWriter does not have to wait for that call to return before processing data.


John


Here is a new version, which syncs every so many bytes, instead of purely by time. I *think* it works better for me.


John

Index: libs/libmythtv/RingBuffer.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/RingBuffer.cpp,v
retrieving revision 1.106
diff -d -u -r1.106 RingBuffer.cpp
--- libs/libmythtv/RingBuffer.cpp	22 Oct 2004 09:32:54 -0000	1.106
+++ libs/libmythtv/RingBuffer.cpp	13 Dec 2004 00:43:49 -0000
@@ -39,6 +39,7 @@
 #define READ_TEST_SIZE 204
 #define OPEN_READ_ATTEMPTS 5
 
+#define SYNC_BYTES (1*1024*1024)
 
 class ThreadedFileWriter
 {
@@ -51,6 +52,7 @@
 
     // Note, this doesn't even try to flush our queue, only ensure that
     // data which has already been sent to the kernel is written to disk
+    void SyncFile(void);
     void Sync(void);
 
     void SetWriteBufferSize(int newSize = TFW_DEF_BUF_SIZE);
@@ -60,6 +62,7 @@
     unsigned BufFree();  /* # of bytes that can be written, without blocking */
 
 protected:
+    static void *boot_fsync(void *);
     static void *boot_writer(void *);
     void DiskLoop(); /* The thread that actually calls write(). */
 
@@ -75,6 +78,8 @@
     pthread_mutex_t buflock;
     int in_dtor;
     pthread_t writer;
+    pthread_t fsync_thread;
+    QWaitCondition syncWait;
     bool no_writes;
     bool flush;
 };
@@ -113,6 +118,14 @@
     return tot;
 }
 
+
+void *ThreadedFileWriter::boot_fsync(void *wotsit)
+{
+    ThreadedFileWriter *fw = (ThreadedFileWriter *)wotsit;
+    fw->SyncFile();
+    return NULL;
+}
+
 void *ThreadedFileWriter::boot_writer(void *wotsit)
 {
     ThreadedFileWriter *fw = (ThreadedFileWriter *)wotsit;
@@ -147,6 +160,7 @@
         tfw_buf_size = TFW_DEF_BUF_SIZE;
         tfw_min_write_size = TFW_MIN_WRITE_SIZE;
         pthread_create(&writer, NULL, boot_writer, this);
+        pthread_create(&fsync_thread, NULL, boot_fsync, this);
     }
 }
 
@@ -158,6 +172,7 @@
     in_dtor = 1; /* tells child thread to exit */
 
     pthread_join(writer, NULL);
+    pthread_join(fsync_thread, NULL);
 
     if (fd >= 0)
         close(fd);
@@ -225,6 +240,19 @@
     flush = false;
 }
 
+void ThreadedFileWriter::SyncFile(void)
+{
+    while (!in_dtor)
+    {
+        syncWait.wait(3000000);
+#ifdef HAVE_FDATASYNC
+        fdatasync(fd);
+#else
+        fsync(fd);
+#endif
+    }
+}
+
 void ThreadedFileWriter::Sync(void)
 {
 #ifdef HAVE_FDATASYNC
@@ -261,8 +289,7 @@
 {
     int size;
     int written = 0;
-    QTime timer;
-    timer.start();
+    size_t sync_size = 0;
 
     while (!in_dtor || BufUsed() > 0)
     {
@@ -276,12 +303,6 @@
             continue;
         }
 
-        if (timer.elapsed() > 1000)
-        {
-            Sync();
-            timer.restart();
-        }
-
         /* cap the max. write size. Prevents the situation where 90% of the
            buffer is valid, and we try to write all of it at once which
            takes a long time. During this time, the other thread fills up
@@ -306,6 +327,13 @@
         {
             written += size;
         }
+
+        sync_size += size;
+        if (sync_size > SYNC_BYTES)
+        {
+            syncWait.wakeAll();
+            sync_size = 0;
+        }
         
         pthread_mutex_lock(&buflock);
         rpos = (rpos + size) % tfw_buf_size;
_______________________________________________
mythtv-dev mailing list
[EMAIL PROTECTED]
http://mythtv.org/cgi-bin/mailman/listinfo/mythtv-dev

Reply via email to