return 1;
}
+#ifndef MAP_POPULATE
+#define MAP_POPULATE 0
+#endif
+
static void recv_afs_result(struct vss_task *vsst, fd_set *rfds)
{
int ret, passed_fd, shmid;
}
mmd->size = statbuf.st_size;
mmd->mtime = statbuf.st_mtime;
- ret = para_mmap(mmd->size, PROT_READ, MAP_PRIVATE, passed_fd,
- 0, &vsst->map);
+ ret = para_mmap(mmd->size, PROT_READ, MAP_PRIVATE | MAP_POPULATE,
+ passed_fd, 0, &vsst->map);
if (ret < 0)
goto err;
close(passed_fd);
}
mmd->chunks_sent++;
mmd->current_chunk++;
+ /*
+ * Prefault next chunk(s)
+ *
+ * If the backing device of the memory-mapped audio file is
+ * slow and read-ahead is turned off or prevented for some
+ * reason, e.g. due to memory pressure, it may take much longer
+ * than the chunk interval to get the next chunk on the wire,
+ * causing buffer underruns on the client side. Mapping the
+ * file with MAP_POPULATE seems to help a bit, but it does not
+ * eliminate the delays completely. Moreover, it is supported
+ * only on Linux. So we do our own read-ahead here.
+ */
+ buf += len;
+ for (i = 0; i < 5 && buf < vsst->map + mmd->size; i++) {
+ __a_unused volatile char x = *buf;
+ buf += 4096;
+ }
}
}