Mercurial > hg > svcore
comparison base/MatrixFileCache.cpp @ 93:27d726916ab3
* Remove mmap-based code again. We can be more efficient with read().
| author | Chris Cannam |
|---|---|
| date | Wed, 03 May 2006 16:47:04 +0000 |
| parents | 1dcf41ed3863 |
| children | 040a151d0897 |
comparison
equal
deleted
inserted
replaced
| 92:4988de098b25 | 93:27d726916ab3 |
|---|---|
| 28 | 28 |
| 29 #include <QFileInfo> | 29 #include <QFileInfo> |
| 30 #include <QFile> | 30 #include <QFile> |
| 31 #include <QDir> | 31 #include <QDir> |
| 32 | 32 |
| 33 //#define HAVE_MMAP 1 | |
| 34 | |
| 35 #ifdef HAVE_MMAP | |
| 36 #include <sys/mman.h> | |
| 37 #endif | |
| 38 | |
| 39 std::map<QString, int> MatrixFileCache::m_refcount; | 33 std::map<QString, int> MatrixFileCache::m_refcount; |
| 40 QMutex MatrixFileCache::m_refcountMutex; | 34 QMutex MatrixFileCache::m_refcountMutex; |
| 41 | 35 |
| 42 //!!! This class is a work in progress -- it does only as much as we | 36 //!!! This class is a work in progress -- it does only as much as we |
| 43 // need for the current SpectrogramLayer. Slated for substantial | 37 // need for the current SpectrogramLayer. Slated for substantial |
| 52 m_autoRegionWidth(256), | 46 m_autoRegionWidth(256), |
| 53 m_off(-1), | 47 m_off(-1), |
| 54 m_rx(0), | 48 m_rx(0), |
| 55 m_rw(0), | 49 m_rw(0), |
| 56 m_userRegion(false), | 50 m_userRegion(false), |
| 57 m_region(0), | 51 m_region(0) |
| 58 m_mmapped(false), | |
| 59 m_mmapSize(0), | |
| 60 m_mmapOff(0), | |
| 61 m_preferMmap(false) | |
| 62 { | 52 { |
| 63 // Ensure header size is a multiple of the size of our data (for | 53 // Ensure header size is a multiple of the size of our data (for |
| 64 // alignment purposes) | 54 // alignment purposes) |
| 65 size_t hs = ((m_headerSize / sizeof(float)) * sizeof(float)); | 55 size_t hs = ((m_headerSize / sizeof(float)) * sizeof(float)); |
| 66 if (hs != m_headerSize) m_headerSize = hs + sizeof(float); | 56 if (hs != m_headerSize) m_headerSize = hs + sizeof(float); |
| 119 } | 109 } |
| 120 | 110 |
| 121 MatrixFileCache::~MatrixFileCache() | 111 MatrixFileCache::~MatrixFileCache() |
| 122 { | 112 { |
| 123 if (m_rw > 0) { | 113 if (m_rw > 0) { |
| 124 if (m_mmapped) { | 114 delete[] m_region; |
| 125 #ifdef HAVE_MMAP | |
| 126 ::munmap(m_region, m_mmapSize); | |
| 127 #endif | |
| 128 } else { | |
| 129 delete[] m_region; | |
| 130 } | |
| 131 } | 115 } |
| 132 | 116 |
| 133 if (m_fd >= 0) { | 117 if (m_fd >= 0) { |
| 134 if (::close(m_fd) < 0) { | 118 if (::close(m_fd) < 0) { |
| 135 ::perror("MatrixFileCache::~MatrixFileCache: close failed"); | 119 ::perror("MatrixFileCache::~MatrixFileCache: close failed"); |
| 171 | 155 |
| 172 off_t off = m_headerSize + (w * h * sizeof(float)); | 156 off_t off = m_headerSize + (w * h * sizeof(float)); |
| 173 | 157 |
| 174 if (w * h > m_width * m_height) { | 158 if (w * h > m_width * m_height) { |
| 175 | 159 |
| 176 #ifdef HAVE_MMAP | 160 /*!!! |
| 177 // If we're going to mmap the file, we need to ensure it's long | 161 // If we're going to mmap the file, we need to ensure it's long |
| 178 // enough beforehand | 162 // enough beforehand |
| 179 | 163 |
| 180 if (m_preferMmap) { | 164 if (m_preferMmap) { |
| 181 | 165 |
| 191 float f(0); | 175 float f(0); |
| 192 if (::write(m_fd, &f, sizeof(float)) != sizeof(float)) { | 176 if (::write(m_fd, &f, sizeof(float)) != sizeof(float)) { |
| 193 ::perror("WARNING: MatrixFileCache::resize: write failed"); | 177 ::perror("WARNING: MatrixFileCache::resize: write failed"); |
| 194 } | 178 } |
| 195 } | 179 } |
| 196 #endif | 180 */ |
| 197 | |
| 198 } else { | 181 } else { |
| 199 | 182 |
| 200 if (::ftruncate(m_fd, off) < 0) { | 183 if (::ftruncate(m_fd, off) < 0) { |
| 201 ::perror("WARNING: MatrixFileCache::resize: ftruncate failed"); | 184 ::perror("WARNING: MatrixFileCache::resize: ftruncate failed"); |
| 202 } | 185 } |
| 356 { | 339 { |
| 357 if (m_rw == 0) return 0; | 340 if (m_rw == 0) return 0; |
| 358 | 341 |
| 359 float *region = m_region; | 342 float *region = m_region; |
| 360 | 343 |
| 361 if (m_mmapOff > 0) { | |
| 362 char *cr = (char *)m_region; | |
| 363 cr += m_mmapOff; | |
| 364 region = (float *)cr; | |
| 365 } | |
| 366 | |
| 367 float *ptr = &(region[(x - m_rx) * m_height + y]); | 344 float *ptr = &(region[(x - m_rx) * m_height + y]); |
| 368 | 345 |
| 369 // std::cerr << "getRegionPtr(" << x << "," << y << "): region is " << m_region << ", returning " << ptr << std::endl; | 346 // std::cerr << "getRegionPtr(" << x << "," << y << "): region is " << m_region << ", returning " << ptr << std::endl; |
| 370 return ptr; | 347 return ptr; |
| 371 } | 348 } |
| 388 { | 365 { |
| 389 if (!user && m_userRegion) return false; | 366 if (!user && m_userRegion) return false; |
| 390 if (m_rw > 0 && x >= m_rx && x + width <= m_rx + m_rw) return true; | 367 if (m_rw > 0 && x >= m_rx && x + width <= m_rx + m_rw) return true; |
| 391 | 368 |
| 392 if (m_rw > 0) { | 369 if (m_rw > 0) { |
| 393 if (m_mmapped) { | 370 delete[] m_region; |
| 394 #ifdef HAVE_MMAP | |
| 395 ::munmap(m_region, m_mmapSize); | |
| 396 std::cerr << "unmapped " << m_mmapSize << " at " << m_region << std::endl; | |
| 397 #endif | |
| 398 } else { | |
| 399 delete[] m_region; | |
| 400 } | |
| 401 m_region = 0; | 371 m_region = 0; |
| 402 m_mmapped = false; | |
| 403 m_mmapSize = 0; | |
| 404 m_mmapOff = 0; | |
| 405 m_rw = 0; | 372 m_rw = 0; |
| 406 } | 373 } |
| 407 | 374 |
| 408 if (width == 0) { | 375 if (width == 0) { |
| 409 return true; | 376 return true; |
| 410 } | 377 } |
| 411 | |
| 412 #ifdef HAVE_MMAP | |
| 413 | |
| 414 if (m_preferMmap) { | |
| 415 | |
| 416 size_t mmapSize = m_height * width * sizeof(float); | |
| 417 off_t offset = m_headerSize + (x * m_height) * sizeof(float); | |
| 418 int pagesize = getpagesize(); | |
| 419 off_t aligned = (offset / pagesize) * pagesize; | |
| 420 size_t mmapOff = offset - aligned; | |
| 421 mmapSize += mmapOff; | |
| 422 | |
| 423 m_region = (float *) | |
| 424 ::mmap(0, mmapSize, PROT_READ, MAP_PRIVATE, m_fd, aligned); | |
| 425 | |
| 426 if (m_region == MAP_FAILED) { | |
| 427 | |
| 428 ::perror("Mmap failed"); | |
| 429 std::cerr << "ERROR: MatrixFileCache::setRegion(" << x << ", " | |
| 430 << width << "): Mmap(0, " << mmapSize | |
| 431 << ", " << PROT_READ << ", " << MAP_SHARED << ", " << m_fd | |
| 432 << ", " << aligned << ") failed, falling back to " | |
| 433 << "non-mmapping code for this cache" << std::endl; | |
| 434 m_preferMmap = false; | |
| 435 | |
| 436 } else { | |
| 437 | |
| 438 std::cerr << "mmap succeeded (offset " << aligned << ", size " << mmapSize << ", m_mmapOff " << mmapOff << ") = " << m_region << std::endl; | |
| 439 | |
| 440 m_mmapped = true; | |
| 441 m_mmapSize = mmapSize; | |
| 442 m_mmapOff = mmapOff; | |
| 443 m_rx = x; | |
| 444 m_rw = width; | |
| 445 if (user) m_userRegion = true; | |
| 446 MUNLOCK(m_region, m_mmapSize); | |
| 447 return true; | |
| 448 } | |
| 449 } | |
| 450 #endif | |
| 451 | 378 |
| 452 if (!seekTo(x, 0)) return false; | 379 if (!seekTo(x, 0)) return false; |
| 453 | 380 |
| 454 m_region = new float[width * m_height]; | 381 m_region = new float[width * m_height]; |
| 455 MUNLOCK(m_region, width * m_height * sizeof(float)); | 382 MUNLOCK(m_region, width * m_height * sizeof(float)); |
