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:
Lennart Poettering 2007-09-02 20:36:32 +00:00
parent 8cf822a3d9
commit 2f7b6fead1
2 changed files with 72 additions and 0 deletions

View file

@ -54,6 +54,10 @@
#include <sys/capability.h> #include <sys/capability.h>
#endif #endif
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
#ifdef HAVE_PTHREAD #ifdef HAVE_PTHREAD
#include <pthread.h> #include <pthread.h>
#endif #endif
@ -1241,3 +1245,69 @@ char *pa_make_path_absolute(const char *p) {
pa_xfree(cwd); pa_xfree(cwd);
return r; 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;
}

View file

@ -100,6 +100,8 @@ char *pa_truncate_utf8(char *c, size_t l);
char *pa_getcwd(void); char *pa_getcwd(void);
char *pa_make_path_absolute(const char *p); 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) { static inline int pa_is_power_of_two(unsigned n) {
return !(n & (n - 1)); return !(n & (n - 1));
} }