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

File mythtv-0.20.2.jobhibernate.patch.txt, 10.8 KB (added by mrsam@…, 18 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: */