Ticket #1791: mythtv-0.20.2.jobhibernate.patch.txt

File mythtv-0.20.2.jobhibernate.patch.txt, 10.8 KB (added by mrsam@…, 12 years ago)

New, refactored patch, against 0.20.2

Line 
1--- programs/mythcommflag/main.cpp.hibernate    2006-08-17 09:53:41.000000000 -0400
2+++ programs/mythcommflag/main.cpp      2007-08-25 17:42:28.000000000 -0400
3@@ -52,6 +52,13 @@
4 
5 int jobID = -1;
6 int lastCmd = -1;
7+JobMonitor *currentJobMonitor;
8+
9+static void rebuild_status_callback(int, void *)
10+{
11+    if (currentJobMonitor)
12+       currentJobMonitor->hibernate();
13+}
14 
15 int BuildVideoMarkup(QString& filename)
16 {
17@@ -82,7 +89,7 @@
18                                                    program_info);
19     nvp->SetRingBuffer(tmprbuf);
20 
21-    nvp->RebuildSeekTable(!quiet);
22+    nvp->RebuildSeekTable(!quiet, rebuild_status_callback);
23 
24     cerr << "Rebuilt\n";
25 
26@@ -255,7 +262,9 @@
27 
28     if (jobID != -1)
29     {
30-        int curCmd = JobQueue::GetJobCmd(jobID);
31+       int curCmd = currentJobMonitor ? currentJobMonitor->GetJobCmd()
32+           : JobQueue::GetJobCmd(jobID);
33+
34         if (curCmd == lastCmd)
35             return;
36 
37@@ -397,6 +406,10 @@
38 
39     program_info->SetCommFlagged(COMM_FLAG_PROCESSING);
40 
41+    JobMonitor monitor(jobID);
42+
43+    currentJobMonitor= jobID == -1 ? NULL: &monitor;
44+
45     CustomEventRelayer cer(incomingCustomEvent);
46     SlotRelayer a(commDetectorBreathe);
47     SlotRelayer b(commDetectorStatusUpdate);
48@@ -447,7 +460,7 @@
49     }
50 
51     delete commDetector;
52-
53+    currentJobMonitor=NULL;
54     return comms_found;
55 }
56 
57@@ -537,7 +550,7 @@
58 
59     if (rebuildSeekTable)
60     {
61-        nvp->RebuildSeekTable();
62+       nvp->RebuildSeekTable(false, rebuild_status_callback);
63 
64         if (!quiet)
65             cerr << "Rebuilt\n";
66--- programs/mythtranscode/transcode.cpp.hibernate      2006-08-23 18:20:59.000000000 -0400
67+++ programs/mythtranscode/transcode.cpp        2007-08-25 17:42:28.000000000 -0400
68@@ -609,6 +609,8 @@
69     QTime flagTime;
70     flagTime.start();
71 
72+    JobMonitor monitor(jobID);
73+
74     while (nvp->TranscodeGetNextFrame(dm_iter, &did_ff, &is_key, honorCutList))
75     {
76         if (first_loop)
77@@ -885,7 +887,7 @@
78 
79             if ((jobID >= 0) || (print_verbose_messages & VB_IMPORTANT))
80             {
81-                if (JobQueue::GetJobCmd(jobID) == JOB_STOP)
82+                if (monitor.GetJobCmd() == JOB_STOP)
83                 {
84                     unlink(outputname);
85                     delete newFrame;
86--- programs/mythtranscode/mpeg2fix.cpp.hibernate       2006-10-03 14:17:33.000000000 -0400
87+++ programs/mythtranscode/mpeg2fix.cpp 2007-08-25 17:42:28.000000000 -0400
88@@ -14,6 +14,7 @@
89 #include <netinet/in.h>
90 #include <getopt.h>
91 #include <stdint.h>
92+#include "jobqueue.h"
93 
94 #ifndef O_LARGEFILE
95 #define O_LARGEFILE 0
96@@ -199,8 +200,11 @@
97 MPEG2fixup::MPEG2fixup(const char *inf, const char *outf,
98                        QMap<long long, int> *deleteMap,
99                        const char *fmt, int norp, int fixPTS, int maxf,
100-                       bool showprog, int otype)
101+                       bool showprog, int otype, int jobIDarg)
102+       : rx(jobID)
103 {
104+    jobID=jobIDarg;
105+
106     displayFrame = new QPtrListIterator<MPEG2frame> (vFrame);
107 
108     infile = inf;
109@@ -429,13 +433,14 @@
110     return (rx->WaitBuffers());
111 }
112 
113-MPEG2replex::MPEG2replex()
114+MPEG2replex::MPEG2replex(int jobIDarg)
115 {
116     memset(&vrbuf, 0, sizeof(ringbuffer));
117     memset(&index_vrbuf, 0, sizeof(ringbuffer));
118     memset(&extrbuf, 0, sizeof(ringbuffer) * N_AUDIO);
119     memset(&index_extrbuf, 0, sizeof(ringbuffer) * N_AUDIO);
120     ext_count = 0;
121+    jobID=jobIDarg;
122 }
123 
124 MPEG2replex::~MPEG2replex()
125@@ -1804,8 +1809,12 @@
126 
127     InitReplex();
128 
129+    JobMonitor monitor(jobID);
130+
131     while (1)
132     {
133+       monitor.hibernate();
134+
135         /* read packet */
136         if (! file_end)
137         {
138@@ -2439,6 +2448,8 @@
139     AVPacket pkt;
140     int count = 0;
141 
142+    JobMonitor monitor(jobID);
143+
144     /*============ initialise AV ===============*/
145     if (!InitAV(file.ascii(), NULL, 0))
146         return TRANSCODE_EXIT_UNKNOWN_ERROR;
147@@ -2447,6 +2458,8 @@
148 
149     while (av_read_frame(inputFC, &pkt) >= 0)
150     {
151+       monitor.hibernate();
152+
153         if (pkt.stream_index == vid_id)
154         {
155             if (pkt.flags & PKT_FLAG_KEY)
156--- programs/mythtranscode/mpeg2fix.h.hibernate 2006-02-18 13:44:52.000000000 -0500
157+++ programs/mythtranscode/mpeg2fix.h   2007-08-25 17:42:28.000000000 -0400
158@@ -102,7 +102,7 @@
159 class MPEG2replex
160 {
161   public:
162-    MPEG2replex();
163+    MPEG2replex(int jobID);
164     ~MPEG2replex();
165     void Start();
166     int WaitBuffers();
167@@ -124,6 +124,7 @@
168 
169   private:
170     multiplex_t *mplex;
171+    int jobID;
172 };
173 
174 class MPEG2fixup
175@@ -131,7 +132,8 @@
176   public:
177     MPEG2fixup(const char *inf, const char *outf,
178                QMap<long long, int> *deleteMap, const char *fmt, int norp,
179-               int fixPTS, int maxf, bool showprog, int otype);
180+               int fixPTS, int maxf, bool showprog, int otype,
181+              int jobID);
182     ~MPEG2fixup();
183     int Start();
184     void AddRangeList(QStringList cutlist, int type);
185@@ -224,6 +226,8 @@
186     QMap<long long, int> delMap;
187     QMap<long long, int> saveMap;
188 
189+    int jobID;
190+
191     pthread_t thread;
192 
193     AVFormatContext *inputFC;
194--- programs/mythtranscode/main.cpp.hibernate   2007-07-14 00:04:20.000000000 -0400
195+++ programs/mythtranscode/main.cpp     2007-08-25 17:42:28.000000000 -0400
196@@ -468,7 +468,7 @@
197       
198         MPEG2fixup *m2f = new MPEG2fixup(infile.ascii(), outfile.ascii(),
199                                          &deleteMap, NULL, false, false, 20,
200-                                         showprogress, otype);
201+                                         showprogress, otype, jobID);
202         if (build_index)
203         {
204             int err = BuildKeyframeIndex(m2f, infile, posMap, jobID);
205--- programs/mythfilldatabase/filldata.cpp.hibernate    2007-08-25 16:20:59.000000000 -0400
206+++ programs/mythfilldatabase/filldata.cpp      2007-08-25 18:29:28.000000000 -0400
207@@ -46,6 +46,8 @@
208 #include "remoteutil.h"
209 #include "videosource.h" // for is_grabber..
210 
211+#include "jobqueue.h"
212+
213 using namespace std;
214 
215 static QString SetupIconCacheDirectory();
216@@ -3942,7 +3944,10 @@
217     gContext->LogEntry("mythfilldatabase", LP_INFO,
218                        "Listings Download Started", "");
219     
220-   
221+    JobMonitor currentJob(-1);
222+
223+    MSqlQuery::currentMonitor= &currentJob;
224+
225     if (!grab_data)
226     {
227     }
228--- libs/libmyth/mythdbcon.cpp.hibernate        2007-08-25 16:20:59.000000000 -0400
229+++ libs/libmyth/mythdbcon.cpp  2007-08-25 17:56:25.000000000 -0400
230@@ -6,6 +6,10 @@
231 #include <qregexp.h>
232 #include <qvaluevector.h>
233 
234+#include "../libmythtv/jobqueue.h"
235+
236+JobMonitor *MSqlQuery::currentMonitor=NULL;
237+
238 MSqlDatabase::MSqlDatabase(const QString &name)
239 {
240     m_name = name;
241@@ -360,6 +364,14 @@
242 
243 bool MSqlQuery::prepare(const QString& query)
244 {
245+       if (currentMonitor)
246+               currentMonitor->hibernate();
247+
248+       return prepareNoCheck(query);
249+}
250+
251+bool MSqlQuery::prepareNoCheck(const QString& query)
252+{
253     static QMutex prepareLock;
254     QMutexLocker lock(&prepareLock);
255     return QSqlQuery::prepare(query);
256--- libs/libmyth/mythdbcon.h.hibernate  2006-04-03 04:58:08.000000000 -0400
257+++ libs/libmyth/mythdbcon.h    2007-08-25 17:53:37.000000000 -0400
258@@ -12,6 +12,8 @@
259 
260 #include "mythcontext.h"
261 
262+class JobMonitor;
263+
264 /// \brief QSqlDatabase wrapper, used by MSqlQuery. Do not use directly.
265 class MSqlDatabase
266 {
267@@ -139,6 +141,12 @@
268     /// \brief Returns dedicated connection. (Required for using temporary SQL tables.)
269     static MSqlQueryInfo DDCon();
270 
271+
272+
273+    bool prepareNoCheck(const QString &query);
274+
275+    static JobMonitor *currentMonitor;
276+
277   private:
278     MSqlDatabase *m_db;
279     bool m_isConnected;
280--- libs/libmythtv/jobqueue.cpp.hibernate       2006-07-30 15:53:33.000000000 -0400
281+++ libs/libmythtv/jobqueue.cpp 2007-08-25 17:57:23.000000000 -0400
282@@ -26,6 +26,10 @@
283 #define LOC     QString("JobQueue: ")
284 #define LOC_ERR QString("JobQueue Error: ")
285 
286+#include <stdio.h>
287+#include <string.h>
288+#include <stdlib.h>
289+
290 JobQueue::JobQueue(bool master)
291 {
292     isMaster = master;
293@@ -972,8 +976,8 @@
294 
295     MSqlQuery query(MSqlQuery::InitCon());
296 
297-    query.prepare("UPDATE jobqueue SET comment = :COMMENT "
298-                  "WHERE id = :ID;");
299+    query.prepareNoCheck("UPDATE jobqueue SET comment = :COMMENT "
300+                        "WHERE id = :ID;");
301 
302     query.bindValue(":COMMENT", comment);
303     query.bindValue(":ID", jobID);
304@@ -2168,4 +2172,124 @@
305     return JOB_NONE;
306 }
307 
308+long JobMonitor::bogomips=0;
309+
310+/*
311+** Add up all bogomips in /proc/cpuinfo
312+*/
313+
314+long JobMonitor::getEstimatedBogoMips()
315+{
316+    if (bogomips)
317+       return bogomips;
318+
319+    FILE *fp=fopen("/proc/cpuinfo", "r");
320+    char linebuf[256];
321+
322+    while (fp && fgets(linebuf, sizeof(linebuf), fp))
323+    {
324+       char *p=strtok(linebuf, " \t:");
325+
326+       if (!p)
327+           continue;
328+
329+       if (strcmp(p, "bogomips") == 0)
330+       {
331+           p=strtok(NULL, " \t:");
332+
333+           if (p)
334+               bogomips += atol(p);
335+       }
336+    }
337+    if (fp) fclose(fp);
338+
339+    return bogomips;
340+}
341+
342+
343+
344+JobMonitor::JobMonitor(int jobIDArg)
345+    : jobID(jobIDArg), jobLastChk(time(NULL)), counter(1),
346+      doMonitor(gContext->GetNumSetting("JobHibernate", -1))
347+{
348+    if (doMonitor < 0)
349+       doMonitor= getEstimatedBogoMips() < 3000;
350+}
351+
352+JobMonitor::~JobMonitor()
353+{
354+}
355+
356+int JobMonitor::GetJobCmd()
357+{
358+    int jobCmd;
359+
360+    while ((jobCmd=JobQueue::GetJobCmd(jobID)) == JOB_RUN)
361+    {
362+       if (!doHibernateCheck())
363+           break;
364+    }
365+
366+    return jobCmd;
367+}
368+
369+void JobMonitor::hibernate()
370+{
371+    while (doHibernateCheck())
372+       ;
373+}
374+
375+bool JobMonitor::doHibernateCheck()
376+{
377+    if (!doMonitor)
378+       return false;
379+
380+    time_t t=time(NULL);
381+
382+    if (t == jobLastChk)
383+       return false;
384+
385+    if (t < jobLastChk)
386+       counter=0; // Time went backwards?
387+    else if (t - jobLastChk > counter)
388+       counter=0;
389+    else
390+       counter -= t - jobLastChk;
391+
392+    jobLastChk=t;
393+
394+    if (counter)
395+       return false;
396+
397+    counter=5;
398+
399+    bool isActive=false;
400+
401+    MSqlQuery query(MSqlQuery::InitCon());
402+    query.prepareNoCheck("SELECT recusage FROM inuseprograms");
403+    if (query.exec() && query.isActive() && query.size() > 0)
404+       while (query.next())
405+       {
406+           QString usage=
407+               query.value(0).toString().lower();
408+
409+           if (usage == "player" ||
410+               usage == "recorder" ||
411+               usage.left(7) == "preview")
412+               isActive=true;
413+       }
414+
415+    if (!isActive)
416+       return false;
417+    counter=1;
418+    if (jobID >= 0 &&
419+       !JobQueue::ChangeJobComment(jobID,
420+                                   "waiting for record/playback to stop"))
421+    {
422+       return false;
423+    }
424+    sleep(5);
425+    return true;
426+}
427+
428 /* vim: set expandtab tabstop=4 shiftwidth=4: */
429--- libs/libmythtv/jobqueue.h.hibernate 2006-07-15 16:13:46.000000000 -0400
430+++ libs/libmythtv/jobqueue.h   2007-08-25 17:42:28.000000000 -0400
431@@ -219,6 +219,30 @@
432     QMutex queueThreadCondLock;
433 };
434 
435+#include <time.h>
436+
437+class JobMonitor {
438+    int jobID;
439+    time_t jobLastChk;
440+    int counter;
441+
442+    int doMonitor;
443+
444+    static long bogomips;
445+
446+ public:
447+    JobMonitor(int jobID);
448+    virtual ~JobMonitor();
449+
450+    int GetJobCmd();
451+    virtual void hibernate();
452+
453+    static long getEstimatedBogoMips();
454+
455+ private:
456+    bool doHibernateCheck();
457+};
458+
459 #endif
460 
461 /* vim: set expandtab tabstop=4 shiftwidth=4: */