comparison data/fft/FFTDataServer.cpp @ 690:1424aa29ae95

Seems to be a bad idea to use plain DEBUG symbol on OS/X (system wants it)
author Chris Cannam
date Tue, 14 Jun 2011 15:26:52 +0100
parents 06f13a3b9e9e
children 97c53dfaf798 e802e550a1f2
comparison
equal deleted inserted replaced
689:573d45e9487b 690:1424aa29ae95
189 distance += ((server->getFFTSize() / fftSize) - 1) * 10; 189 distance += ((server->getFFTSize() / fftSize) - 1) * 10;
190 190
191 if (server->getFillCompletion() < 50) distance += 100; 191 if (server->getFillCompletion() < 50) distance += 100;
192 192
193 #ifdef DEBUG_FFT_SERVER 193 #ifdef DEBUG_FFT_SERVER
194 DEBUG << "FFTDataServer::getFuzzyInstance: Distance for server " << server << " is " << distance << ", best is " << bestdist << endl; 194 SVDEBUG << "FFTDataServer::getFuzzyInstance: Distance for server " << server << " is " << distance << ", best is " << bestdist << endl;
195 #endif 195 #endif
196 196
197 if (bestdist == -1 || distance < bestdist) { 197 if (bestdist == -1 || distance < bestdist) {
198 bestdist = distance; 198 bestdist = distance;
199 best = i; 199 best = i;
202 } 202 }
203 203
204 if (bestdist >= 0) { 204 if (bestdist >= 0) {
205 FFTDataServer *server = best->second.first; 205 FFTDataServer *server = best->second.first;
206 #ifdef DEBUG_FFT_SERVER 206 #ifdef DEBUG_FFT_SERVER
207 DEBUG << "FFTDataServer::getFuzzyInstance: We like server " << server << " (with distance " << bestdist << ")" << endl; 207 SVDEBUG << "FFTDataServer::getFuzzyInstance: We like server " << server << " (with distance " << bestdist << ")" << endl;
208 #endif 208 #endif
209 claimInstance(server, false); 209 claimInstance(server, false);
210 return server; 210 return server;
211 } 211 }
212 } 212 }
226 226
227 FFTDataServer * 227 FFTDataServer *
228 FFTDataServer::findServer(QString n) 228 FFTDataServer::findServer(QString n)
229 { 229 {
230 #ifdef DEBUG_FFT_SERVER 230 #ifdef DEBUG_FFT_SERVER
231 DEBUG << "FFTDataServer::findServer(\"" << n << "\")" << endl; 231 SVDEBUG << "FFTDataServer::findServer(\"" << n << "\")" << endl;
232 #endif 232 #endif
233 233
234 if (m_servers.find(n) != m_servers.end()) { 234 if (m_servers.find(n) != m_servers.end()) {
235 235
236 FFTDataServer *server = m_servers[n].first; 236 FFTDataServer *server = m_servers[n].first;
237 237
238 #ifdef DEBUG_FFT_SERVER 238 #ifdef DEBUG_FFT_SERVER
239 DEBUG << "FFTDataServer::findServer(\"" << n << "\"): found " << server << endl; 239 SVDEBUG << "FFTDataServer::findServer(\"" << n << "\"): found " << server << endl;
240 #endif 240 #endif
241 241
242 claimInstance(server, false); 242 claimInstance(server, false);
243 243
244 return server; 244 return server;
245 } 245 }
246 246
247 #ifdef DEBUG_FFT_SERVER 247 #ifdef DEBUG_FFT_SERVER
248 DEBUG << "FFTDataServer::findServer(\"" << n << "\"): not found" << endl; 248 SVDEBUG << "FFTDataServer::findServer(\"" << n << "\"): not found" << endl;
249 #endif 249 #endif
250 250
251 return 0; 251 return 0;
252 } 252 }
253 253
262 { 262 {
263 MutexLocker locker(needLock ? &m_serverMapMutex : 0, 263 MutexLocker locker(needLock ? &m_serverMapMutex : 0,
264 "FFTDataServer::claimInstance::m_serverMapMutex"); 264 "FFTDataServer::claimInstance::m_serverMapMutex");
265 265
266 #ifdef DEBUG_FFT_SERVER 266 #ifdef DEBUG_FFT_SERVER
267 DEBUG << "FFTDataServer::claimInstance(" << server << ")" << endl; 267 SVDEBUG << "FFTDataServer::claimInstance(" << server << ")" << endl;
268 #endif 268 #endif
269 269
270 for (ServerMap::iterator i = m_servers.begin(); i != m_servers.end(); ++i) { 270 for (ServerMap::iterator i = m_servers.begin(); i != m_servers.end(); ++i) {
271 if (i->second.first == server) { 271 if (i->second.first == server) {
272 272
273 for (ServerQueue::iterator j = m_releasedServers.begin(); 273 for (ServerQueue::iterator j = m_releasedServers.begin();
274 j != m_releasedServers.end(); ++j) { 274 j != m_releasedServers.end(); ++j) {
275 275
276 if (*j == server) { 276 if (*j == server) {
277 #ifdef DEBUG_FFT_SERVER 277 #ifdef DEBUG_FFT_SERVER
278 DEBUG << "FFTDataServer::claimInstance: found in released server list, removing from it" << endl; 278 SVDEBUG << "FFTDataServer::claimInstance: found in released server list, removing from it" << endl;
279 #endif 279 #endif
280 m_releasedServers.erase(j); 280 m_releasedServers.erase(j);
281 break; 281 break;
282 } 282 }
283 } 283 }
284 284
285 ++i->second.second; 285 ++i->second.second;
286 286
287 #ifdef DEBUG_FFT_SERVER 287 #ifdef DEBUG_FFT_SERVER
288 DEBUG << "FFTDataServer::claimInstance: new refcount is " << i->second.second << endl; 288 SVDEBUG << "FFTDataServer::claimInstance: new refcount is " << i->second.second << endl;
289 #endif 289 #endif
290 290
291 return; 291 return;
292 } 292 }
293 } 293 }
307 { 307 {
308 MutexLocker locker(needLock ? &m_serverMapMutex : 0, 308 MutexLocker locker(needLock ? &m_serverMapMutex : 0,
309 "FFTDataServer::releaseInstance::m_serverMapMutex"); 309 "FFTDataServer::releaseInstance::m_serverMapMutex");
310 310
311 #ifdef DEBUG_FFT_SERVER 311 #ifdef DEBUG_FFT_SERVER
312 DEBUG << "FFTDataServer::releaseInstance(" << server << ")" << endl; 312 SVDEBUG << "FFTDataServer::releaseInstance(" << server << ")" << endl;
313 #endif 313 #endif
314 314
315 // -- if ref count > 0, decrement and return 315 // -- if ref count > 0, decrement and return
316 // -- if the instance hasn't been used at all, delete it immediately 316 // -- if the instance hasn't been used at all, delete it immediately
317 // -- if fewer than N instances (N = e.g. 3) remain with zero refcounts, 317 // -- if fewer than N instances (N = e.g. 3) remain with zero refcounts,
330 << server << "): instance not allocated" << std::endl; 330 << server << "): instance not allocated" << std::endl;
331 } else if (--i->second.second == 0) { 331 } else if (--i->second.second == 0) {
332 /*!!! 332 /*!!!
333 if (server->m_lastUsedCache == -1) { // never used 333 if (server->m_lastUsedCache == -1) { // never used
334 #ifdef DEBUG_FFT_SERVER 334 #ifdef DEBUG_FFT_SERVER
335 DEBUG << "FFTDataServer::releaseInstance: instance " 335 SVDEBUG << "FFTDataServer::releaseInstance: instance "
336 << server << " has never been used, erasing" 336 << server << " has never been used, erasing"
337 << endl; 337 << endl;
338 #endif 338 #endif
339 delete server; 339 delete server;
340 m_servers.erase(i); 340 m_servers.erase(i);
341 } else { 341 } else {
342 */ 342 */
343 #ifdef DEBUG_FFT_SERVER 343 #ifdef DEBUG_FFT_SERVER
344 DEBUG << "FFTDataServer::releaseInstance: instance " 344 SVDEBUG << "FFTDataServer::releaseInstance: instance "
345 << server << " no longer in use, marking for possible collection" 345 << server << " no longer in use, marking for possible collection"
346 << endl; 346 << endl;
347 #endif 347 #endif
348 bool found = false; 348 bool found = false;
349 for (ServerQueue::iterator j = m_releasedServers.begin(); 349 for (ServerQueue::iterator j = m_releasedServers.begin();
359 server->suspend(); 359 server->suspend();
360 purgeLimbo(); 360 purgeLimbo();
361 //!!! } 361 //!!! }
362 } else { 362 } else {
363 #ifdef DEBUG_FFT_SERVER 363 #ifdef DEBUG_FFT_SERVER
364 DEBUG << "FFTDataServer::releaseInstance: instance " 364 SVDEBUG << "FFTDataServer::releaseInstance: instance "
365 << server << " now has refcount " << i->second.second 365 << server << " now has refcount " << i->second.second
366 << endl; 366 << endl;
367 #endif 367 #endif
368 } 368 }
369 return; 369 return;
376 376
377 void 377 void
378 FFTDataServer::purgeLimbo(int maxSize) 378 FFTDataServer::purgeLimbo(int maxSize)
379 { 379 {
380 #ifdef DEBUG_FFT_SERVER 380 #ifdef DEBUG_FFT_SERVER
381 DEBUG << "FFTDataServer::purgeLimbo(" << maxSize << "): " 381 SVDEBUG << "FFTDataServer::purgeLimbo(" << maxSize << "): "
382 << m_releasedServers.size() << " candidates" << endl; 382 << m_releasedServers.size() << " candidates" << endl;
383 #endif 383 #endif
384 384
385 while (int(m_releasedServers.size()) > maxSize) { 385 while (int(m_releasedServers.size()) > maxSize) {
386 386
387 FFTDataServer *server = *m_releasedServers.begin(); 387 FFTDataServer *server = *m_releasedServers.begin();
388 388
389 bool found = false; 389 bool found = false;
390 390
391 #ifdef DEBUG_FFT_SERVER 391 #ifdef DEBUG_FFT_SERVER
392 DEBUG << "FFTDataServer::purgeLimbo: considering candidate " 392 SVDEBUG << "FFTDataServer::purgeLimbo: considering candidate "
393 << server << endl; 393 << server << endl;
394 #endif 394 #endif
395 395
396 for (ServerMap::iterator i = m_servers.begin(); i != m_servers.end(); ++i) { 396 for (ServerMap::iterator i = m_servers.begin(); i != m_servers.end(); ++i) {
397 397
403 << i->second.second << std::endl; 403 << i->second.second << std::endl;
404 // ... so don't delete it 404 // ... so don't delete it
405 break; 405 break;
406 } 406 }
407 #ifdef DEBUG_FFT_SERVER 407 #ifdef DEBUG_FFT_SERVER
408 DEBUG << "FFTDataServer::purgeLimbo: looks OK, erasing it" 408 SVDEBUG << "FFTDataServer::purgeLimbo: looks OK, erasing it"
409 << endl; 409 << endl;
410 #endif 410 #endif
411 411
412 m_servers.erase(i); 412 m_servers.erase(i);
413 delete server; 413 delete server;
424 424
425 m_releasedServers.pop_front(); 425 m_releasedServers.pop_front();
426 } 426 }
427 427
428 #ifdef DEBUG_FFT_SERVER 428 #ifdef DEBUG_FFT_SERVER
429 DEBUG << "FFTDataServer::purgeLimbo(" << maxSize << "): " 429 SVDEBUG << "FFTDataServer::purgeLimbo(" << maxSize << "): "
430 << m_releasedServers.size() << " remain" << endl; 430 << m_releasedServers.size() << " remain" << endl;
431 #endif 431 #endif
432 432
433 } 433 }
434 434
437 { 437 {
438 MutexLocker locker(&m_serverMapMutex, 438 MutexLocker locker(&m_serverMapMutex,
439 "FFTDataServer::modelAboutToBeDeleted::m_serverMapMutex"); 439 "FFTDataServer::modelAboutToBeDeleted::m_serverMapMutex");
440 440
441 #ifdef DEBUG_FFT_SERVER 441 #ifdef DEBUG_FFT_SERVER
442 DEBUG << "FFTDataServer::modelAboutToBeDeleted(" << model << ")" 442 SVDEBUG << "FFTDataServer::modelAboutToBeDeleted(" << model << ")"
443 << endl; 443 << endl;
444 #endif 444 #endif
445 445
446 for (ServerMap::iterator i = m_servers.begin(); i != m_servers.end(); ++i) { 446 for (ServerMap::iterator i = m_servers.begin(); i != m_servers.end(); ++i) {
447 447
448 FFTDataServer *server = i->second.first; 448 FFTDataServer *server = i->second.first;
449 449
450 if (server->getModel() == model) { 450 if (server->getModel() == model) {
451 451
452 #ifdef DEBUG_FFT_SERVER 452 #ifdef DEBUG_FFT_SERVER
453 DEBUG << "FFTDataServer::modelAboutToBeDeleted: server is " 453 SVDEBUG << "FFTDataServer::modelAboutToBeDeleted: server is "
454 << server << endl; 454 << server << endl;
455 #endif 455 #endif
456 456
457 if (i->second.second > 0) { 457 if (i->second.second > 0) {
458 std::cerr << "WARNING: FFTDataServer::modelAboutToBeDeleted: Model " << model << " (\"" << model->objectName() << "\") is about to be deleted, but is still being referred to by FFT server " << server << " with non-zero refcount " << i->second.second << std::endl; 458 std::cerr << "WARNING: FFTDataServer::modelAboutToBeDeleted: Model " << model << " (\"" << model->objectName() << "\") is about to be deleted, but is still being referred to by FFT server " << server << " with non-zero refcount " << i->second.second << std::endl;
461 } 461 }
462 for (ServerQueue::iterator j = m_releasedServers.begin(); 462 for (ServerQueue::iterator j = m_releasedServers.begin();
463 j != m_releasedServers.end(); ++j) { 463 j != m_releasedServers.end(); ++j) {
464 if (*j == server) { 464 if (*j == server) {
465 #ifdef DEBUG_FFT_SERVER 465 #ifdef DEBUG_FFT_SERVER
466 DEBUG << "FFTDataServer::modelAboutToBeDeleted: erasing from released servers" << endl; 466 SVDEBUG << "FFTDataServer::modelAboutToBeDeleted: erasing from released servers" << endl;
467 #endif 467 #endif
468 m_releasedServers.erase(j); 468 m_releasedServers.erase(j);
469 break; 469 break;
470 } 470 }
471 } 471 }
472 #ifdef DEBUG_FFT_SERVER 472 #ifdef DEBUG_FFT_SERVER
473 DEBUG << "FFTDataServer::modelAboutToBeDeleted: erasing server" << endl; 473 SVDEBUG << "FFTDataServer::modelAboutToBeDeleted: erasing server" << endl;
474 #endif 474 #endif
475 m_servers.erase(i); 475 m_servers.erase(i);
476 delete server; 476 delete server;
477 return; 477 return;
478 } 478 }
839 FFTDataServer::makeCacheReader(int c) 839 FFTDataServer::makeCacheReader(int c)
840 { 840 {
841 // preconditions: m_caches[c] exists and contains a file writer; 841 // preconditions: m_caches[c] exists and contains a file writer;
842 // m_cacheVectorLock is not locked by this thread 842 // m_cacheVectorLock is not locked by this thread
843 #ifdef DEBUG_FFT_SERVER 843 #ifdef DEBUG_FFT_SERVER
844 DEBUG << "FFTDataServer::makeCacheReader(" << c << ")" << endl; 844 SVDEBUG << "FFTDataServer::makeCacheReader(" << c << ")" << endl;
845 #endif 845 #endif
846 846
847 QThread *me = QThread::currentThread(); 847 QThread *me = QThread::currentThread();
848 QWriteLocker locker(&m_cacheVectorLock); 848 QWriteLocker locker(&m_cacheVectorLock);
849 CacheBlock *cb(m_caches.at(c)); 849 CacheBlock *cb(m_caches.at(c));
873 } 873 }
874 874
875 cb = m_caches.at(deleteCandidate); 875 cb = m_caches.at(deleteCandidate);
876 if (cb && cb->fileCacheReader.find(me) != cb->fileCacheReader.end()) { 876 if (cb && cb->fileCacheReader.find(me) != cb->fileCacheReader.end()) {
877 #ifdef DEBUG_FFT_SERVER 877 #ifdef DEBUG_FFT_SERVER
878 DEBUG << "FFTDataServer::makeCacheReader: Deleting probably unpopular reader " << deleteCandidate << " for this thread (as I create reader " << c << ")" << endl; 878 SVDEBUG << "FFTDataServer::makeCacheReader: Deleting probably unpopular reader " << deleteCandidate << " for this thread (as I create reader " << c << ")" << endl;
879 #endif 879 #endif
880 delete cb->fileCacheReader[me]; 880 delete cb->fileCacheReader[me];
881 cb->fileCacheReader.erase(me); 881 cb->fileCacheReader.erase(me);
882 } 882 }
883 883
899 if (!cache) return 0; 899 if (!cache) return 0;
900 900
901 if (!cache->haveSetColumnAt(col)) { 901 if (!cache->haveSetColumnAt(col)) {
902 Profiler profiler("FFTDataServer::getMagnitudeAt: filling"); 902 Profiler profiler("FFTDataServer::getMagnitudeAt: filling");
903 #ifdef DEBUG_FFT_SERVER 903 #ifdef DEBUG_FFT_SERVER
904 DEBUG << "FFTDataServer::getMagnitudeAt: calling fillColumn(" 904 SVDEBUG << "FFTDataServer::getMagnitudeAt: calling fillColumn("
905 << x << ")" << endl; 905 << x << ")" << endl;
906 #endif 906 #endif
907 fillColumn(x); 907 fillColumn(x);
908 } 908 }
909 909
1128 } 1128 }
1129 1129
1130 if (!cache->haveSetColumnAt(col)) { 1130 if (!cache->haveSetColumnAt(col)) {
1131 Profiler profiler("FFTDataServer::getValuesAt: filling"); 1131 Profiler profiler("FFTDataServer::getValuesAt: filling");
1132 #ifdef DEBUG_FFT_SERVER 1132 #ifdef DEBUG_FFT_SERVER
1133 DEBUG << "FFTDataServer::getValuesAt(" << x << ", " << y << "): filling" << endl; 1133 SVDEBUG << "FFTDataServer::getValuesAt(" << x << ", " << y << "): filling" << endl;
1134 #endif 1134 #endif
1135 fillColumn(x); 1135 fillColumn(x);
1136 } 1136 }
1137 1137
1138 cache->getValuesAt(col, y, real, imaginary); 1138 cache->getValuesAt(col, y, real, imaginary);
1187 1187
1188 if (!haveCache(x)) { 1188 if (!haveCache(x)) {
1189 /*!!! 1189 /*!!!
1190 if (m_lastUsedCache == -1) { 1190 if (m_lastUsedCache == -1) {
1191 if (m_suspended) { 1191 if (m_suspended) {
1192 DEBUG << "FFTDataServer::isColumnReady(" << x << "): no cache, calling resume" << endl; 1192 SVDEBUG << "FFTDataServer::isColumnReady(" << x << "): no cache, calling resume" << endl;
1193 resume(); 1193 resume();
1194 } 1194 }
1195 m_fillThread->start(); 1195 m_fillThread->start();
1196 } 1196 }
1197 */ 1197 */
1256 1256
1257 startFrame -= winsize / 2; 1257 startFrame -= winsize / 2;
1258 endFrame -= winsize / 2; 1258 endFrame -= winsize / 2;
1259 1259
1260 #ifdef DEBUG_FFT_SERVER_FILL 1260 #ifdef DEBUG_FFT_SERVER_FILL
1261 DEBUG << "FFTDataServer::fillColumn: requesting frames " 1261 SVDEBUG << "FFTDataServer::fillColumn: requesting frames "
1262 << startFrame + pfx << " -> " << endFrame << " ( = " 1262 << startFrame + pfx << " -> " << endFrame << " ( = "
1263 << endFrame - (startFrame + pfx) << ") at index " 1263 << endFrame - (startFrame + pfx) << ") at index "
1264 << off + pfx << " in buffer of size " << m_fftSize 1264 << off + pfx << " in buffer of size " << m_fftSize
1265 << " with window size " << m_windowSize 1265 << " with window size " << m_windowSize
1266 << " from channel " << m_channel << endl; 1266 << " from channel " << m_channel << endl;
1368 m_workbuffer, 1368 m_workbuffer,
1369 m_workbuffer + hs + 1); 1369 m_workbuffer + hs + 1);
1370 } 1370 }
1371 1371
1372 if (m_suspended) { 1372 if (m_suspended) {
1373 // DEBUG << "FFTDataServer::fillColumn(" << x << "): calling resume" << endl; 1373 // SVDEBUG << "FFTDataServer::fillColumn(" << x << "): calling resume" << endl;
1374 // resume(); 1374 // resume();
1375 } 1375 }
1376 } 1376 }
1377 1377
1378 void 1378 void
1444 1444
1445 void 1445 void
1446 FFTDataServer::FillThread::run() 1446 FFTDataServer::FillThread::run()
1447 { 1447 {
1448 #ifdef DEBUG_FFT_SERVER_FILL 1448 #ifdef DEBUG_FFT_SERVER_FILL
1449 DEBUG << "FFTDataServer::FillThread::run()" << endl; 1449 SVDEBUG << "FFTDataServer::FillThread::run()" << endl;
1450 #endif 1450 #endif
1451 1451
1452 m_extent = 0; 1452 m_extent = 0;
1453 m_completion = 0; 1453 m_completion = 0;
1454 1454
1455 while (!m_server.m_model->isReady() && !m_server.m_exiting) { 1455 while (!m_server.m_model->isReady() && !m_server.m_exiting) {
1456 #ifdef DEBUG_FFT_SERVER_FILL 1456 #ifdef DEBUG_FFT_SERVER_FILL
1457 DEBUG << "FFTDataServer::FillThread::run(): waiting for model " << m_server.m_model << " to be ready" << endl; 1457 SVDEBUG << "FFTDataServer::FillThread::run(): waiting for model " << m_server.m_model << " to be ready" << endl;
1458 #endif 1458 #endif
1459 sleep(1); 1459 sleep(1);
1460 } 1460 }
1461 if (m_server.m_exiting) return; 1461 if (m_server.m_exiting) return;
1462 1462
1474 for (size_t f = m_fillFrom; f < end; f += m_server.m_windowIncrement) { 1474 for (size_t f = m_fillFrom; f < end; f += m_server.m_windowIncrement) {
1475 1475
1476 try { 1476 try {
1477 m_server.fillColumn(int((f - start) / m_server.m_windowIncrement)); 1477 m_server.fillColumn(int((f - start) / m_server.m_windowIncrement));
1478 } catch (std::exception &e) { 1478 } catch (std::exception &e) {
1479 DEBUG << "FFTDataServer::FillThread::run: exception: " << e.what() << endl; 1479 SVDEBUG << "FFTDataServer::FillThread::run: exception: " << e.what() << endl;
1480 m_error = e.what(); 1480 m_error = e.what();
1481 m_server.fillComplete(); 1481 m_server.fillComplete();
1482 m_completion = 100; 1482 m_completion = 100;
1483 m_extent = end; 1483 m_extent = end;
1484 return; 1484 return;
1523 for (size_t f = start; f < remainingEnd; f += m_server.m_windowIncrement) { 1523 for (size_t f = start; f < remainingEnd; f += m_server.m_windowIncrement) {
1524 1524
1525 try { 1525 try {
1526 m_server.fillColumn(int((f - start) / m_server.m_windowIncrement)); 1526 m_server.fillColumn(int((f - start) / m_server.m_windowIncrement));
1527 } catch (std::exception &e) { 1527 } catch (std::exception &e) {
1528 DEBUG << "FFTDataServer::FillThread::run: exception: " << e.what() << endl; 1528 SVDEBUG << "FFTDataServer::FillThread::run: exception: " << e.what() << endl;
1529 m_error = e.what(); 1529 m_error = e.what();
1530 m_server.fillComplete(); 1530 m_server.fillComplete();
1531 m_completion = 100; 1531 m_completion = 100;
1532 m_extent = end; 1532 m_extent = end;
1533 return; 1533 return;
1565 m_server.fillComplete(); 1565 m_server.fillComplete();
1566 m_completion = 100; 1566 m_completion = 100;
1567 m_extent = end; 1567 m_extent = end;
1568 1568
1569 #ifdef DEBUG_FFT_SERVER 1569 #ifdef DEBUG_FFT_SERVER
1570 DEBUG << "FFTDataServer::FillThread::run exiting" << endl; 1570 SVDEBUG << "FFTDataServer::FillThread::run exiting" << endl;
1571 #endif 1571 #endif
1572 } 1572 }
1573 1573