Utilise the new gethugepagesizes call to implement getpagesizes() call
returning all page sizes on the system, both base page sizes and all
hugepage sizes.

Signed-off-by: Andy Whitcroft <[EMAIL PROTECTED]>
---
 hugetlbfs.h              |    1 +
 hugeutils.c              |   27 +++++++++++++++
 tests/gethugepagesizes.c |   84 +++++++++++++++++++++++++++++++++++++---------
 3 files changed, 96 insertions(+), 16 deletions(-)

diff --git a/hugetlbfs.h b/hugetlbfs.h
index 985e138..3f2eb30 100644
--- a/hugetlbfs.h
+++ b/hugetlbfs.h
@@ -23,6 +23,7 @@
 
 long gethugepagesize(void);
 int gethugepagesizes(long pagesizes[], int n_elem);
+int getpagesizes(long pagesizes[], int n_elem);
 int hugetlbfs_test_path(const char *mount);
 long hugetlbfs_test_pagesize(const char *mount);
 const char *hugetlbfs_find_path(void);
diff --git a/hugeutils.c b/hugeutils.c
index 03d059e..afd6933 100644
--- a/hugeutils.c
+++ b/hugeutils.c
@@ -626,6 +626,33 @@ int gethugepagesizes(long pagesizes[], int n_elem)
        return nr_sizes;
 }
 
+int getpagesizes(long pagesizes[], int n_elem)
+{
+       int ret;
+
+       if (n_elem < 0 || (n_elem > 0 && pagesizes == NULL)) {
+               errno = EINVAL;
+               return -1;
+       }
+
+       /* Requests for sizing, we need one more slot than gethugepagesizes. */
+       if (pagesizes == NULL && n_elem == 0) {
+               ret = gethugepagesizes(pagesizes, n_elem);
+
+       } else {
+               /* Install the base page size. */
+               if (n_elem && pagesizes)
+                       pagesizes[0] = sysconf(_SC_PAGESIZE);
+                if (n_elem == 1)
+                        return 1;
+
+               ret = gethugepagesizes(pagesizes + 1, n_elem - 1);
+       }
+       if (ret < 0)
+               return ret;
+       return ret + 1;
+}
+
 int hugetlbfs_test_path(const char *mount)
 {
        struct statfs64 sb;
diff --git a/tests/gethugepagesizes.c b/tests/gethugepagesizes.c
index 44aff68..0cd97ed 100644
--- a/tests/gethugepagesizes.c
+++ b/tests/gethugepagesizes.c
@@ -72,6 +72,8 @@ DIR *opendir(const char *name)
        }
 }
 
+#define HPAGE_SIZE (16 * 1024)
+
 /*
  * Override read_meminfo to simulate various conditions
  */
@@ -86,7 +88,7 @@ long read_meminfo(const char *tag)
 
        switch (meminfo_state) {
                case OVERRIDE_OFF:      return real_read_meminfo(tag);
-               case OVERRIDE_ON:       return 16 * 1024;
+               case OVERRIDE_ON:       return HPAGE_SIZE;
                default:                return -1;
        }
 }
@@ -141,10 +143,8 @@ void cleanup(void)
                cleanup_fake_sysfs();
 }
 
-#define INIT_SIZES(a, v1, v2, v3) {a[0] = v1; a[1] = v2; a[2] = v3; a[3] = -1;}
-
-void expect_sizes(int line, int expected, int actual,
-                       long expected_sizes[], long actual_sizes[])
+void validate_sizes(int line, long actual_sizes[], int actual, int max_actual,
+                       long expected_sizes[], int expected)
 {
        int i, j;
        if (expected != actual)
@@ -159,12 +159,37 @@ void expect_sizes(int line, int expected, int actual,
                        FAIL("Line %i: Expected size %li not found in actual "
                                "results", line, expected_sizes[i]);
        }
+
+       for (i = expected; i < max_actual; i++)
+               if (actual_sizes[i] != 42)
+                       FAIL("Line %i: Wrote past official limit at %i",
+                               line, i);
 }
 
+#define MAX 16
+#define EXPECT_SIZES(func, max, count, expected)                       \
+({                                                                     \
+       long __a[MAX] = { [0 ... MAX-1] = 42 };                         \
+       int __na;                                                       \
+       int __l = (count < max) ? count : max;                          \
+                                                                       \
+       __na = func(__a, max);                                          \
+                                                                       \
+       validate_sizes(__LINE__, __a, __na, MAX, expected, __l);        \
+                                                                       \
+       __na;                                                           \
+})
+
+#define INIT_LIST(a, values...)                                                
\
+({                                                                     \
+       long __e[] = { values };                                        \
+       memcpy(a, __e, sizeof(__e));                                    \
+})
+
 int main(int argc, char *argv[])
 {
-       long expected_sizes[4], actual_sizes[4], meminfo_size;
-       int nr_sizes;
+       long expected_sizes[MAX], actual_sizes[MAX], meminfo_size;
+       long base_size = sysconf(_SC_PAGESIZE);
 
        test_init(argc, argv);
 
@@ -175,11 +200,17 @@ int main(int argc, char *argv[])
         */
        meminfo_state = OVERRIDE_OFF;
        sysfs_state = OVERRIDE_OFF;
+
        if (gethugepagesizes(actual_sizes, -1) != -1 || errno != EINVAL)
                FAIL("Mishandled params (n_elem < 0)");
        if (gethugepagesizes(NULL, 1) != -1 || errno != EINVAL)
                FAIL("Mishandled params (pagesizes == NULL, n_elem > 0)");
 
+       if (getpagesizes(actual_sizes, -1) != -1 || errno != EINVAL)
+               FAIL("Mishandled params (n_elem < 0)");
+       if (getpagesizes(NULL, 1) != -1 || errno != EINVAL)
+               FAIL("Mishandled params (pagesizes == NULL, n_elem > 0)");
+
        /*
         * ===
         * Test some corner cases using a fake system configuration
@@ -190,8 +221,11 @@ int main(int argc, char *argv[])
         * Check handling when /proc/meminfo indicates no huge page support
         */
        meminfo_state = OVERRIDE_MISSING;
-       if (gethugepagesizes(actual_sizes, 1) != 0 || errno != 0)
-               FAIL("Incorrect handling when huge page support is missing");
+
+       EXPECT_SIZES(gethugepagesizes, MAX, 0, expected_sizes);
+
+       INIT_LIST(expected_sizes, base_size);
+       EXPECT_SIZES(getpagesizes, MAX, 1, expected_sizes);
 
        /*
         * When the sysfs heirarchy is not present ...
@@ -201,26 +235,44 @@ int main(int argc, char *argv[])
        /* ... only the meminfo size is returned. */
        meminfo_state = OVERRIDE_ON;
        meminfo_size = read_meminfo("Hugepagesize:") * 1024;
-       INIT_SIZES(expected_sizes, meminfo_size, -1, -1);
 
-       /* Use 2 to give the function the chance to return too many sizes */
-       nr_sizes = gethugepagesizes(actual_sizes, 2);
-       expect_sizes(__LINE__, 1, nr_sizes, expected_sizes, actual_sizes);
+       INIT_LIST(expected_sizes, meminfo_size);
+       EXPECT_SIZES(gethugepagesizes, MAX, 1, expected_sizes);
+
+       INIT_LIST(expected_sizes, base_size, meminfo_size);
+       EXPECT_SIZES(getpagesizes, MAX, 2, expected_sizes);
 
        /*
         * When sysfs defines additional sizes ...
         */
-       INIT_SIZES(expected_sizes, meminfo_size, 1024, 2048);
+       INIT_LIST(expected_sizes, meminfo_size, 1024 * 1024, 2048 * 1024);
+
        setup_fake_sysfs(expected_sizes, 3);
        sysfs_state = OVERRIDE_ON;
 
        /* ... make sure all sizes are returned without duplicates */
-       nr_sizes = gethugepagesizes(actual_sizes, 4);
-       expect_sizes(__LINE__, 3, nr_sizes, expected_sizes, actual_sizes);
+       /* ... while making sure we do not overstep our limit */
+       EXPECT_SIZES(gethugepagesizes, MAX, 3, expected_sizes);
+       EXPECT_SIZES(gethugepagesizes, 1, 3, expected_sizes);
+       EXPECT_SIZES(gethugepagesizes, 2, 3, expected_sizes);
+       EXPECT_SIZES(gethugepagesizes, 3, 3, expected_sizes);
+       EXPECT_SIZES(gethugepagesizes, 4, 3, expected_sizes);
+
+       INIT_LIST(expected_sizes,
+                       base_size, meminfo_size, 1024 * 1024, 2048 * 1024);
+       EXPECT_SIZES(getpagesizes, MAX, 4, expected_sizes);
+       EXPECT_SIZES(getpagesizes, 1, 4, expected_sizes);
+       EXPECT_SIZES(getpagesizes, 2, 4, expected_sizes);
+       EXPECT_SIZES(getpagesizes, 3, 4, expected_sizes);
+       EXPECT_SIZES(getpagesizes, 4, 4, expected_sizes);
+       EXPECT_SIZES(getpagesizes, 5, 4, expected_sizes);
 
        /* ... we can check how many sizes are supported. */
        if (gethugepagesizes(NULL, 0) != 3)
                FAIL("Unable to check the number of supported sizes");
 
+       if (getpagesizes(NULL, 0) != 4)
+               FAIL("Unable to check the number of supported sizes");
+
        PASS();
 }
-- 
1.6.0.1.451.gc8d31


-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Libhugetlbfs-devel mailing list
Libhugetlbfs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libhugetlbfs-devel

Reply via email to