mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-05 13:29:57 -05:00
add new pa_will_need() API for paging in memory
git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1745 fefdeb5f-60dc-0310-8127-8f9354f1896f
This commit is contained in:
parent
8cf822a3d9
commit
2f7b6fead1
2 changed files with 72 additions and 0 deletions
|
|
@ -54,6 +54,10 @@
|
|||
#include <sys/capability.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PTHREAD
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
|
@ -1241,3 +1245,69 @@ char *pa_make_path_absolute(const char *p) {
|
|||
pa_xfree(cwd);
|
||||
return r;
|
||||
}
|
||||
|
||||
void *pa_will_need(const void *p, size_t l) {
|
||||
#ifdef RLIMIT_MEMLOCK
|
||||
struct rlimit rlim;
|
||||
#endif
|
||||
const void *a;
|
||||
size_t size;
|
||||
int r;
|
||||
size_t bs;
|
||||
|
||||
pa_assert(p);
|
||||
pa_assert(l > 0);
|
||||
|
||||
a = PA_PAGE_ALIGN_PTR(p);
|
||||
size = (const uint8_t*) p + l - (const uint8_t*) a;
|
||||
|
||||
if ((r = posix_madvise((void*) a, size, POSIX_MADV_WILLNEED)) == 0) {
|
||||
pa_log_debug("posix_madvise() worked fine!");
|
||||
return (void*) p;
|
||||
}
|
||||
|
||||
/* Most likely the memory was not mmap()ed from a file and thus
|
||||
* madvise() didn't work, so let's misuse mlock() do page this
|
||||
* stuff back into RAM. Yeah, let's fuck with the MM! It's so
|
||||
* inviting, the man page of mlock() tells us: "All pages that
|
||||
* contain a part of the specified address range are guaranteed to
|
||||
* be resident in RAM when the call returns successfully." */
|
||||
|
||||
#ifdef RLIMIT_MEMLOCK
|
||||
pa_assert_se(getrlimit(RLIMIT_MEMLOCK, &rlim) == 0);
|
||||
|
||||
if (rlim.rlim_cur < PA_PAGE_SIZE) {
|
||||
pa_log_debug("posix_madvise() failed, resource limits don't allow mlock(), can't page in data: %s", pa_cstrerror(r));
|
||||
return (void*) p;
|
||||
}
|
||||
|
||||
bs = PA_PAGE_ALIGN(rlim.rlim_cur);
|
||||
#else
|
||||
bs = PA_PAGE_SIZE*4;
|
||||
#endif
|
||||
|
||||
pa_log_debug("posix_madvise() failed, trying mlock(): %s", pa_cstrerror(r));
|
||||
|
||||
while (size > 0 && bs > 0) {
|
||||
|
||||
if (bs > size)
|
||||
bs = size;
|
||||
|
||||
if (mlock(a, bs) < 0) {
|
||||
bs = PA_PAGE_ALIGN(bs / 2);
|
||||
continue;
|
||||
}
|
||||
|
||||
pa_assert_se(munlock(a, bs) == 0);
|
||||
|
||||
a = (const uint8_t*) a + bs;
|
||||
size -= bs;
|
||||
}
|
||||
|
||||
if (bs <= 0)
|
||||
pa_log_debug("mlock() failed too, giving up: %s", pa_cstrerror(errno));
|
||||
else
|
||||
pa_log_debug("mlock() worked fine!");
|
||||
|
||||
return (void*) p;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,6 +100,8 @@ char *pa_truncate_utf8(char *c, size_t l);
|
|||
char *pa_getcwd(void);
|
||||
char *pa_make_path_absolute(const char *p);
|
||||
|
||||
void *pa_will_need(const void *p, size_t l);
|
||||
|
||||
static inline int pa_is_power_of_two(unsigned n) {
|
||||
return !(n & (n - 1));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue