You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by mt...@apache.org on 2009/08/31 14:56:56 UTC

svn commit: r809567 - in /commons/sandbox/runtime/trunk/src: main/java/org/apache/commons/runtime/io/ main/native/include/ main/native/os/unix/ main/native/os/win32/ main/native/test/ test/org/apache/commons/runtime/

Author: mturk
Date: Mon Aug 31 12:56:55 2009
New Revision: 809567

URL: http://svn.apache.org/viewvc?rev=809567&view=rev
Log:
Initial mmap code

Modified:
    commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/FileOpenMode.java
    commons/sandbox/runtime/trunk/src/main/native/include/acr_file.h
    commons/sandbox/runtime/trunk/src/main/native/include/acr_mmap.h
    commons/sandbox/runtime/trunk/src/main/native/os/unix/ios.c
    commons/sandbox/runtime/trunk/src/main/native/os/unix/pmmap.c
    commons/sandbox/runtime/trunk/src/main/native/os/win32/pmmap.c
    commons/sandbox/runtime/trunk/src/main/native/test/testcase.c
    commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestPrivate.java

Modified: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/FileOpenMode.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/FileOpenMode.java?rev=809567&r1=809566&r2=809567&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/FileOpenMode.java (original)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/FileOpenMode.java Mon Aug 31 12:56:55 2009
@@ -27,6 +27,10 @@
     READ(               0x00001),
     /** Open the file for writing. */
     WRITE(              0x00002),
+    /** Open the file for reading and writing.
+     * This is convenience for {@code READ + WRITE}.
+     */
+    RDWR(               0x00003),
     /** Create the file if not there. */
     CREATE(             0x00004),
     /** Append to the end of the file. */
@@ -41,17 +45,18 @@
     BUFFERED(           0x00080),
     /** Delete the file after close. */
     DELONCLOSE(         0x00100),
-
     /** Platform dependent support for higher level locked read/write
      * access to support writes across process/machines.
      */
     SHARELOCK(          0x00400),
-
     /** Advisory flag that this file should support
      * socket sendfile operation.
      */
     SENDFILE_ENABLED(   0x01000),
-
+    /** Flag that is used for mapping pages in memory so
+     * they may be executed.
+     */
+    EXEC(               0x02000),
     /** Platform dependent flag to enable sparse file support.
      */
     SPARSE(             0x08000);
@@ -94,8 +99,13 @@
     {
         EnumSet<FileOpenMode> set = EnumSet.noneOf(FileOpenMode.class);
         for (FileOpenMode e : values()) {
-            if ((e.value & value) == e.value)
-                set.add(e);
+            if ((e.value & value) == e.value) {
+                /* Don't add the convenience RDWR.
+                 * Both READ and WRITE will be added instead
+                 */
+                if (e != RDWR)
+                    set.add(e);
+            }
         }
         return set;
     }

Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr_file.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr_file.h?rev=809567&r1=809566&r2=809567&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/acr_file.h (original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/acr_file.h Mon Aug 31 12:56:55 2009
@@ -75,6 +75,7 @@
 
 #define ACR_FOPEN_READ       0x00001  /**< Open the file for reading */
 #define ACR_FOPEN_WRITE      0x00002  /**< Open the file for writing */
+#define ACR_FOPEN_RDWR       0x00003  /**< Convenience for READ | WRITE */
 #define ACR_FOPEN_CREATE     0x00004  /**< Create the file if not there */
 #define ACR_FOPEN_APPEND     0x00008  /**< Append to the end of the file */
 #define ACR_FOPEN_TRUNCATE   0x00010  /**< Open the file and truncate
@@ -91,12 +92,18 @@
                                          process/machines */
 #define ACR_FOPEN_NOCLEANUP  0x00800  /**< Do not register a cleanup
                                          when the file is opened */
-#define ACR_FOPEN_SENDFILE_ENABLED 0x01000 /**< Advisory flag that this
-                                             file should support
-                                             apr_socket_sendfile operation */
-#define ACR_FOPEN_SPARSE      0x08000 /**< Platform dependent flag to enable
+#define ACR_FOPEN_EXEC       0x02000  /**< Platform dependent flag to enable
+                                       * executable page memory mappings
+                                       */
+#define ACR_FOPEN_SPARSE     0x08000  /**< Platform dependent flag to enable
                                        * sparse file support, see WARNING below
                                        */
+
+#define ACR_FOPEN_SENDFILE_ENABLED 0x01000 /**< Advisory flag that this
+                                            * file should support sendfile
+                                            * operation.
+                                            */
+
 /**
  * @defgroup apr_file_attrs_set_flags File Attribute Flags
  * @{

Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr_mmap.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr_mmap.h?rev=809567&r1=809566&r2=809567&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/acr_mmap.h (original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/acr_mmap.h Mon Aug 31 12:56:55 2009
@@ -38,20 +38,31 @@
 
 
 /**
+ * Create a memory map from the given file descriptod.
+ * @param env JNI environment to use.
+ * @param fd A file descriptor to use.
+ * @param flags File and memory open flags.
+ * @see ACR_FOPEN_ flags
+ */
+ACR_DECLARE(int) ACR_MMapCreate(JNIEnv *env, int fd, int flags);
+
+/**
  * Create and initialize a memory map that can be used to map the files
  * in memory.
  * @param env JNI environment to use.
  * @param fname A file name to use.
+ * @param flags File and memory open flags.
+ * @see ACR_FOPEN_ flags
  */
-ACR_DECLARE(int) ACR_MmapCreate(JNIEnv *env, const acr_pchar_t *fname);
-
+ACR_DECLARE(int) ACR_MMapOpen(JNIEnv *env, const acr_pchar_t *fname,
+                              int flags);
 
 /**
  * Close the memory map.
  * @param env JNI environment to use.
  * @param map the mmap to close.
  */
-ACR_DECLARE(int) ACR_MmapClose(JNIEnv *env, int map);
+ACR_DECLARE(int) ACR_MMapClose(JNIEnv *env, int map);
 
 #ifdef __cplusplus
 }

Modified: commons/sandbox/runtime/trunk/src/main/native/os/unix/ios.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/ios.c?rev=809567&r1=809566&r2=809567&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/unix/ios.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/unix/ios.c Mon Aug 31 12:56:55 2009
@@ -187,7 +187,6 @@
         return -1;
     }
     pthread_mutex_lock(&ios_lock);
-
     for (i = __bmp_hint; i < __bmp_size; i++) {
         if (__bitmap[i] != 0xFF) {
             x = (i << 3) + __sbit_mask[__bitmap[i]];
@@ -310,16 +309,22 @@
 {
     int i;
     int l = 0;
+    int f = 0;
     fprintf(stdout, "\nDumping IOH statistics...\n");
     fprintf(stdout, "Bitmap mask    : %d\n", acr_ioh_mask);
     fprintf(stdout, "Bitmap size    : %d\n", __bmp_size);
+    fprintf(stdout, "Tolal  size    : %d\n", __ioh_size);
     fprintf(stdout, "Bitmap hint    : %d\n", __bmp_hint);
     for (i = 0; i < __bmp_size; i++) {
         if (__bitmap[i] != 0xFF) {
             l += (8 - __sbit_mask[__bitmap[i]]);
         }
+        else {
+            f++;
+        }
     }
     fprintf(stdout, "Bitmap free    : %d\n", l);
+    fprintf(stdout, "Bitmap full    : %d\n", f);
     fflush(stdout);
 }
 

Modified: commons/sandbox/runtime/trunk/src/main/native/os/unix/pmmap.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/pmmap.c?rev=809567&r1=809566&r2=809567&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/unix/pmmap.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/unix/pmmap.c Mon Aug 31 12:56:55 2009
@@ -27,5 +27,160 @@
 #include "acr_memory.h"
 #include "acr_string.h"
 #include "acr_descriptor.h"
+#include "acr_file.h"
 #include "acr_mmap.h"
 
+#include <sys/mman.h>
+
+#define MMAP_OWNS_FILE 1
+
+struct acr_mmap_t {
+    int             fd;
+    int             flags;
+    acr_size_t      size;
+    void           *base;
+};
+
+static int mmap_cleanup(void *map, int type, unsigned int flags)
+{
+    int rc = 0;
+    acr_mmap_t *m = (acr_mmap_t *)map;
+
+    if (type != ACR_DT_MMAP) {
+        return ACR_EFTYPE;
+    }
+    if (IS_VALID_HANDLE(m->base)) {
+        if (munmap(m->base, m->size))
+            rc = ACR_GET_OS_ERROR();
+    }
+    if (flags == MMAP_OWNS_FILE) {
+        /* Since we have opended the file close it.
+         */
+        if (close(m->fd))
+            rc = ACR_GET_OS_ERROR();
+    }
+    free(m);
+    return rc;
+}
+
+static int mmap_descriptor_cleanup(ACR_JNISTDARGS,
+                                   acr_descriptor_cb_type_e cm,
+                                   acr_descriptor_cb_t *dp)
+{
+    int rc = ACR_SUCCESS;
+
+    switch (cm) {
+        case ACR_DESC_CLOSE:
+            if (dp->di > 0)
+                rc = acr_ioh_close(dp->di);
+            else
+                rc = ACR_EBADF;
+        break;
+        case ACR_DESC_SYNC:
+            if (dp->di > 0) {
+                acr_mmap_t *m = (acr_mmap_t *)ACR_IOH(dp->di);
+                if (ACR_IOH_TYPE(dp->di) != ACR_DT_MMAP)
+                    rc = ACR_EFTYPE;
+                else {
+                    if (msync(m->base, m->size, MS_SYNC | MS_INVALIDATE)) {
+                        /* This will return ACR_EBUSY if some other memory
+                         * mapped region is locked
+                         */
+                        rc = ACR_GET_OS_ERROR();
+                    }
+                }
+            }
+            else
+                rc = ACR_EBADF;
+        break;
+        default:
+            rc = ACR_ENOTIMPL;
+        break;
+    }
+    return rc;
+}
+
+ACR_DECLARE(int) ACR_MMapClose(JNIEnv *_E, int map)
+{
+    int rc;
+
+    if (ACR_IOH_TYPE(map) != ACR_DT_MMAP) {
+        ACR_THROW_EX_IF_ERR(ACR_EX_EINVAL, ACR_EFTYPE);
+        return ACR_EFTYPE;
+    }
+    rc = acr_ioh_close(map);
+    ACR_THROW_IO_IF_ERR(rc);
+    return rc;
+}
+
+ACR_DECLARE(int) ACR_MMapCreate(JNIEnv *_E, int fd, int flags)
+{
+    int rc;
+    acr_mmap_t *map;
+    acr_file_t *file;
+
+    file = (acr_file_t *)ACR_IOH(fd);
+    if (ACR_IOH_TYPE(fd) != ACR_DT_FILE) {
+        ACR_THROW_EX_IF_ERR(ACR_EX_EINVAL, ACR_EFTYPE);
+        return -1;
+    }
+    if (file->fd < 0) {
+        ACR_THROW_EX_IF_ERR(ACR_EX_EINVAL, ACR_EBADF);
+        return -1;
+    }
+    map = ACR_Calloc(_E, THROW_FMARK, sizeof(acr_mmap_t));
+    if (!map)
+        return -1;
+
+    map->fd = file->fd;
+    if (flags & ACR_FOPEN_WRITE)
+        map->flags |= PROT_WRITE;
+    if (flags & ACR_FOPEN_READ)
+        map->flags |= PROT_READ;
+
+    rc = acr_ioh_open(map, ACR_DT_MMAP, 0, mmap_cleanup);
+    return rc;
+}
+
+ACR_DECLARE(int) ACR_MMapOpen(JNIEnv *_E, const acr_pchar_t *filename,
+                              int flags)
+{
+    int rc;
+    acr_mmap_t *map;
+    int fd;
+    int oflags = 0;
+
+    if (flags & ACR_FOPEN_READ)
+        oflags = O_RDONLY;
+    if (flags & ACR_FOPEN_WRITE)
+        oflags = O_RDWR;
+    fd = open(filename, oflags);
+    if (fd < 0) {
+        ACR_THROW_IO_ERRNO();
+        return -1;
+    }
+    map = ACR_Calloc(_E, THROW_FMARK, sizeof(acr_mmap_t));
+    if (!map) {
+        return -1;
+    }
+    if (flags & ACR_FOPEN_READ) {
+        map->flags |= PROT_READ;
+        oflags      = O_RDONLY;
+    }
+    if (flags & ACR_FOPEN_WRITE) {
+        map->flags |= PROT_WRITE;
+        oflags      = O_RDWR;
+    }
+    if (flags & ACR_FOPEN_EXEC)
+        map->flags |= PROT_EXEC;
+    map->fd = open(filename, oflags);
+    if (map->fd < 0) {
+        rc =  ACR_GET_OS_ERROR();
+        free(map);
+        ACR_SET_OS_ERROR(rc);
+        return -1;
+    }
+
+    rc = acr_ioh_open(map, ACR_DT_MMAP, MMAP_OWNS_FILE, mmap_cleanup);
+    return rc;
+}

Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/pmmap.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/pmmap.c?rev=809567&r1=809566&r2=809567&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/pmmap.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/pmmap.c Mon Aug 31 12:56:55 2009
@@ -27,5 +27,131 @@
 #include "acr_memory.h"
 #include "acr_string.h"
 #include "acr_descriptor.h"
+#include "acr_file.h"
 #include "acr_mmap.h"
 
+#define MMAP_OWNS_FILE 1
+
+struct acr_mmap_t {
+    HANDLE          fd;
+    HANDLE          mh;
+    int             flags;
+    acr_size_t      size;
+    void           *base;
+};
+
+static int mmap_cleanup(void *map, int type, unsigned int flags)
+{
+    int rc = 0;
+    acr_mmap_t *m = (acr_mmap_t *)map;
+
+    if (type != ACR_DT_MMAP) {
+        return ACR_EFTYPE;
+    }
+    if (IS_VALID_HANDLE(m->base)) {
+        if (!UnmapViewOfFile(m->base))
+            rc = ACR_GET_OS_ERROR();
+    }
+    if (CloseHandle(m->mh))
+        rc = ACR_GET_OS_ERROR();
+    if (flags == MMAP_OWNS_FILE) {
+        /* Since we have opended the file close it.
+         */
+        if (CloseHandle(m->fd))
+            rc = ACR_GET_OS_ERROR();
+    }
+    free(m);
+    return rc;
+}
+
+static int mmap_descriptor_cleanup(ACR_JNISTDARGS,
+                                   acr_descriptor_cb_type_e cm,
+                                   acr_descriptor_cb_t *dp)
+{
+    int rc = ACR_SUCCESS;
+
+    switch (cm) {
+        case ACR_DESC_CLOSE:
+            if (dp->di > 0)
+                rc = acr_ioh_close(dp->di);
+            else
+                rc = ACR_EBADF;
+        break;
+        case ACR_DESC_SYNC:
+            if (dp->di > 0) {
+                acr_mmap_t *m = (acr_mmap_t *)ACR_IOH(dp->di);
+                if (ACR_IOH_TYPE(dp->di) != ACR_DT_MMAP)
+                    rc = ACR_EFTYPE;
+                else {
+                    if (!FlushViewOfFile(m->base, m->size)) {
+                        /* Error during flushing.
+                         */
+                        rc = ACR_GET_OS_ERROR();
+                    }
+                }
+            }
+            else
+                rc = ACR_EBADF;
+        break;
+        default:
+            rc = ACR_ENOTIMPL;
+        break;
+    }
+    return rc;
+}
+
+ACR_DECLARE(int) ACR_MMapClose(JNIEnv *_E, int map)
+{
+    int rc;
+
+    if (ACR_IOH_TYPE(map) != ACR_DT_MMAP) {
+        ACR_THROW_EX_IF_ERR(ACR_EX_EINVAL, ACR_EFTYPE);
+        return ACR_EFTYPE;
+    }
+    rc = acr_ioh_close(map);
+    ACR_THROW_IO_IF_ERR(rc);
+    return rc;
+}
+
+ACR_DECLARE(int) ACR_MMapCreate(JNIEnv *_E, int fd, int flags)
+{
+    int rc;
+    acr_mmap_t *map;
+    acr_file_t *file;
+
+    file = (acr_file_t *)ACR_IOH(fd);
+    if (ACR_IOH_TYPE(fd) != ACR_DT_FILE) {
+        ACR_THROW_EX_IF_ERR(ACR_EX_EINVAL, ACR_EFTYPE);
+        return -1;
+    }
+    if (IS_INVALID_HANDLE(file->fd)) {
+        ACR_THROW_EX_IF_ERR(ACR_EX_EINVAL, ACR_EBADF);
+        return -1;
+    }
+    map = ACR_Calloc(_E, THROW_FMARK, sizeof(acr_mmap_t));
+    if (!map)
+        return -1;
+
+    map->fd = file->fd;
+    if (flags & ACR_FOPEN_READ) {
+        if (flags & ACR_FOPEN_EXEC)
+            map->flags = PAGE_EXECUTE_READ;
+        else
+            map->flags = PAGE_READONLY;
+    }
+    if (flags & ACR_FOPEN_WRITE) {
+        if (flags & ACR_FOPEN_EXEC)
+            map->flags = PAGE_EXECUTE_READWRITE;
+        else
+            map->flags = PAGE_READWRITE;
+    }
+    map->mh = CreateFileMappingW(map->fh, NULL, map->flags, 0, 0, NULL);
+    if (IS_INVALID_HANDLE(map->mh)) {
+        rc = ACR_GET_OS_ERROR();
+        free(map);
+        ACR_SET_OS_ERROR(rc);
+        return -1;
+    }
+    rc = acr_ioh_open(map, ACR_DT_MMAP, 0, mmap_cleanup);
+    return rc;
+}

Modified: commons/sandbox/runtime/trunk/src/main/native/test/testcase.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/test/testcase.c?rev=809567&r1=809566&r2=809567&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/test/testcase.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/test/testcase.c Mon Aug 31 12:56:55 2009
@@ -611,6 +611,11 @@
     int fd;
     int n;
     int r = 0;
+    int *slots;
+
+    slots = (int *)calloc(sizeof(int), ACR_IOH_SLOTS);
+    if (!slots)
+        return -1;
 
     srandom(time(NULL));
     for (n = 0; n < 2; n++) {
@@ -619,12 +624,19 @@
             if (fd == -1) {
                 r++;
             }
+            else {
+                slots[i] = fd;
+            }
         }
         for (i = 0; i < ACR_IOH_SLOTS; i++) {
             fd = random() %  ACR_IOH_SLOTS;
-            acr_ioh_free(i);
+            if (slots[i]) {
+                acr_ioh_free(slots[i]);
+                slots[i] = 0;
+            }
         }
     }
+    free(slots);
     return r;
 }
 
@@ -643,20 +655,24 @@
     for (n = 0; n < 2; n++) {
         for (i = 0; i < (ACR_IOH_SLOTS - 8); i++) {
             fd = acr_ioh_alloc(NULL, ACR_DT_FILE, i);
-            slots[fd] = fd;
             if (fd == -1) {
                 r++;
             }
+            else
+                slots[i] = fd;
         }
         for (i = 0; i < ACR_IOH_SLOTS; i++) {
             fd = random() %  ACR_IOH_SLOTS;
-            if (slots[fd])
-                acr_ioh_free(fd);
-            slots[fd] = 0;
+            if (slots[fd]) {
+                acr_ioh_free(slots[fd]);
+                slots[fd] = 0;
+            }
         }
         for (i = 0; i < ACR_IOH_SLOTS; i++) {
-            if (slots[i])
+            if (slots[i]) {
                 acr_ioh_free(slots[i]);
+                slots[i] = 0;
+            }
         }
     }
     free(slots);

Modified: commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestPrivate.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestPrivate.java?rev=809567&r1=809566&r2=809567&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestPrivate.java (original)
+++ commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestPrivate.java Mon Aug 31 12:56:55 2009
@@ -143,6 +143,7 @@
     public void testExInt()
         throws Exception
     {
+        test054(0);
         try {
             test000(0);
             fail("Exception not thrown");
@@ -675,13 +676,16 @@
     {
         int r = 0;
         int f = 0;
+        test054(0);
         long s = System.currentTimeMillis();
 		for (int i = 0; i < 2; i++) {
 		    r += test050(i);
+            test054(0);
 		}
         long p = System.currentTimeMillis();
 		for (int i = 0; i < 2; i++) {
 		    f += test051(i);
+            test054(0);
 		}
         long e = System.currentTimeMillis();
 		System.out.println();
@@ -727,28 +731,33 @@
         }
         public int testCallback(Object o, int num)
         {
-            int fd = 0;
+            int i;
+            int [] fd = new int[100];
             try {
-                fd = test052(num);
+                for (i = 0; i < 100; i++)
+                    fd[i] = test052(num);
                 Thread.sleep(1);
             } catch (Exception e) {
                 // Ignore
             }
-            test053(fd);
+            for (i = 0; i < 100; i++)
+                test053(fd[i]);
             synchronized (IohParallelWorker.class) {
                ((IohParallelWorker)o).numCalls++;
             }
-            if (fd < 1)
-                return 1;
-            else
-                return 0;
+            for (i = 0; i < 100; i++) {
+                if (fd[i] < 1)
+                    return 1;
+            }
+            return 0;
         }
     }
 
     public void testIOHParallel()
         throws Throwable
     {
-        int numThreads = 250;
+        test054(0);
+        int numThreads = 100;
         IohParallelWorker wo = new IohParallelWorker();
         TestParallel pt = new TestParallel(numThreads);
         int rv = pt.run(wo, wo, 1000);
@@ -757,7 +766,7 @@
         System.out.println("Parallel test status " + rv);
         System.out.println("Parallel test calls  " + nc);
         System.out.println("Parallel test called " + wo.numCalls);
-        assertEquals("Number of tests", wo.numCalls, nc);
+        assertEquals("Number of tests", wo.numCalls * 100, nc);
     }
 
     public void testDescriptorNativeIntSet()