auto import from //depot/cupcake/@135843
diff --git a/simulator/app/Shmem.cpp b/simulator/app/Shmem.cpp
new file mode 100644
index 0000000..4c619c2
--- /dev/null
+++ b/simulator/app/Shmem.cpp
@@ -0,0 +1,558 @@
+//
+// Copyright 2005 The Android Open Source Project
+//
+// Shared memory interface.
+//
+#include "Shmem.h"
+#include "utils/Log.h"
+
+#if defined(HAVE_MACOSX_IPC) || defined(HAVE_ANDROID_IPC)
+#  include <sys/mman.h>
+#  include <fcntl.h>
+#  include <unistd.h>
+#elif defined(HAVE_SYSV_IPC)
+# include <sys/types.h>
+# include <sys/ipc.h>
+# include <sys/shm.h>
+#elif defined(HAVE_WIN32_IPC)
+# include <windows.h>
+#else
+# error "unknown shm config"
+#endif
+
+#include <errno.h>
+#include <assert.h>
+
+using namespace android;
+
+
+#if defined(HAVE_MACOSX_IPC) || defined(HAVE_ANDROID_IPC)
+
+/*
+ * SysV IPC under Mac OS X seems to have problems.  It works fine on
+ * some machines but totally fails on others.  We're working around it
+ * here by using mmap().
+ */
+
+#define kInvalidHandle  ((unsigned long)-1)
+
+static const char* kShmemFile = "/tmp/android-";
+
+/*
+ * Constructor.  Just set up the fields.
+ */
+Shmem::Shmem(void)
+    : mHandle(kInvalidHandle), mAddr(MAP_FAILED), mLength(-1), mCreator(false),
+      mKey(-1)
+{
+}
+
+/*
+ * Destructor.  Detach and, if we created it, mark the segment for
+ * destruction.
+ */
+Shmem::~Shmem(void)
+{
+    if (mAddr != MAP_FAILED)
+        munmap(mAddr, mLength);
+    if ((long)mHandle >= 0) {
+        close(mHandle);
+
+        if (mCreator) {
+            char nameBuf[64];
+            int cc;
+
+            snprintf(nameBuf, sizeof(nameBuf), "%s%d", kShmemFile, mKey);
+            cc = unlink(nameBuf);
+            if (cc != 0) {
+                LOG(LOG_WARN, "shmem", "Couldn't clean up '%s'\n", nameBuf);
+                /* oh well */
+            }
+        }
+    }
+}
+
+/*
+ * Create the segment and attach ourselves to it.
+ */
+bool Shmem::create(int key, long size, bool deleteExisting)
+{
+    char nameBuf[64];
+    int fd, cc;
+
+    snprintf(nameBuf, sizeof(nameBuf), "%s%d", kShmemFile, key);
+
+    if (deleteExisting) {
+        cc = unlink(nameBuf);
+        if (cc != 0 && errno != ENOENT) {
+            LOG(LOG_ERROR, "shmem", "Failed to remove old map file '%s'\n",
+                nameBuf);
+            return false;
+        }
+    }
+
+    fd = open(nameBuf, O_CREAT|O_EXCL|O_RDWR, 0600);
+    if (fd < 0) {
+        LOG(LOG_ERROR, "shmem", "Unable to create map file '%s' (errno=%d)\n",
+            nameBuf, errno);
+        return false;
+    }
+
+    /*
+     * Set the file size by seeking and writing.
+     */
+    if (ftruncate(fd, size) == -1) {
+        LOG(LOG_ERROR, "shmem", "Unable to set file size in '%s' (errno=%d)\n",
+            nameBuf, errno);
+        close(fd);
+        return false;
+    }
+
+    mAddr = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+    if (mAddr == MAP_FAILED) {
+        LOG(LOG_ERROR, "shmem", "mmap failed (errno=%d)\n", errno);
+        close(fd);
+        return false;
+    }
+
+    mHandle = fd;
+    mLength = size;
+    mCreator = true;
+    mKey = key;
+
+    /* done with shmem, create the associated semaphore */
+    if (!mSem.create(key, 1, true)) {
+        LOG(LOG_ERROR, "shmem",
+            "Failed creating semaphore for Shmem (key=%d)\n", key);
+        return false;
+    }
+
+    return true;
+}
+
+/*
+ * Attach ourselves to an existing segment.
+ */
+bool Shmem::attach(int key)
+{
+    char nameBuf[64];
+    int fd;
+
+    snprintf(nameBuf, sizeof(nameBuf), "%s%d", kShmemFile, key);
+    fd = open(nameBuf, O_RDWR, 0600);
+    if (fd < 0) {
+        LOG(LOG_ERROR, "shmem", "Unable to open map file '%s' (errno=%d)\n",
+            nameBuf, errno);
+        return false;
+    }
+
+    off_t len;
+    len = lseek(fd, 0, SEEK_END);
+    if (len == (off_t) -1) {
+        LOG(LOG_ERROR, "shmem",
+            "Could not determine file size of '%s' (errno=%d)\n",
+            nameBuf, errno);
+        close(fd);
+        return false;
+    }
+
+    mAddr = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+    if (mAddr == MAP_FAILED) {
+        LOG(LOG_ERROR, "shmem", "mmap failed (errno=%d)\n", errno);
+        close(fd);
+        return false;
+    }
+
+    mHandle = fd;
+    mLength = len;
+    assert(mCreator == false);
+    mKey = key;
+
+    /* done with shmem, attach to associated semaphore */
+    if (!mSem.attach(key)) {
+        LOG(LOG_ERROR, "shmem",
+            "Failed to attach to semaphore for Shmem (key=%d)\n", key);
+        return false;
+    }
+
+    return true;
+}
+
+/*
+ * Get address.
+ */
+void* Shmem::getAddr(void)
+{
+    assert(mAddr != MAP_FAILED);
+    return mAddr;
+}
+
+/*
+ * Return the length of the segment.
+ *
+ * Returns -1 on failure.
+ */
+long Shmem::getLength(void)
+{
+    if (mLength >= 0)
+        return mLength;
+
+    // we should always have it by now
+    assert(false);
+    return -1;
+}
+
+
+#elif defined(HAVE_SYSV_IPC) // ----------------------------------------------
+
+/*
+ * SysV-style IPC.  The SysV shared memory API is fairly annoying to
+ * deal with, but it's present on many UNIX-like systems.
+ */
+
+#define kInvalidHandle  ((unsigned long)-1)
+
+/*
+ * Constructor.  Just set up the fields.
+ */
+Shmem::Shmem(void)
+    : mHandle(kInvalidHandle), mAddr(NULL), mLength(-1), mCreator(false),
+      mKey(-1)
+{
+}
+
+/*
+ * Destructor.  Detach and, if we created it, mark the segment for
+ * destruction.
+ */
+Shmem::~Shmem(void)
+{
+    int cc;
+
+    //LOG(LOG_DEBUG, "shmem", "~Shmem(handle=%ld creator=%d)",
+    //    mHandle, mCreator);
+
+    if (mAddr != NULL)
+        cc = shmdt(mAddr);
+
+    if (mCreator && mHandle != kInvalidHandle) {
+        cc = shmctl((int) mHandle, IPC_RMID, NULL);
+        if (cc != 0) {
+            LOG(LOG_WARN, "shmem",
+                "Destructor failed to remove shmid=%ld (errno=%d)\n",
+                mHandle, errno);
+        }
+    }
+}
+
+/*
+ * Create the segment and attach ourselves to it.
+ */
+bool Shmem::create(int key, long size, bool deleteExisting)
+{
+    int shmid, cc;
+
+    if (deleteExisting) {
+        shmid = shmget(key, size, 0);
+        if (shmid != -1) {
+            LOG(LOG_DEBUG, "shmem",
+                "Key %d exists (shmid=%d), marking for destroy", key, shmid);
+            cc = shmctl(shmid, IPC_RMID, NULL);
+            if (cc != 0) {
+                LOG(LOG_ERROR, "shmem",
+                    "Failed to remove key=%d shmid=%d (errno=%d)\n",
+                    key, shmid, errno);
+                return false;   // IPC_CREAT | IPC_EXCL will fail, so bail now
+            } else {
+                LOG(LOG_DEBUG, "shmem",
+                    "Removed previous segment with key=%d\n", key);
+            }
+        }
+    }
+
+    shmid = shmget(key, size, 0600 | IPC_CREAT | IPC_EXCL);
+    if (shmid == -1) {
+        LOG(LOG_ERROR, "shmem", "Failed to create key=%d (errno=%d)\n",
+            key, errno);
+        return false;
+    }
+
+    mHandle = shmid;
+    mCreator = true;
+    mKey = key;
+
+    void* addr = shmat(shmid, NULL, 0);
+    if (addr == (void*) -1) {
+        LOG(LOG_ERROR, "shmem",
+            "Could not attach to key=%d shmid=%d (errno=%d)\n",
+            key, shmid, errno);
+        return false;
+    }
+
+    mAddr = addr;
+    mLength = size;
+
+    /* done with shmem, create the associated semaphore */
+    if (!mSem.create(key, 1, true)) {
+        LOG(LOG_ERROR, "shmem",
+            "Failed creating semaphore for Shmem (key=%d)\n", key);
+        return false;
+    }
+
+    return true;
+}
+
+/*
+ * Attach ourselves to an existing segment.
+ */
+bool Shmem::attach(int key)
+{
+    int shmid;
+
+    shmid = shmget(key, 0, 0);
+    if (shmid == -1) {
+        LOG(LOG_ERROR, "shmem", "Failed to find key=%d\n", key);
+        return false;
+    }
+
+    mHandle = shmid;
+    assert(mCreator == false);
+    mKey = key;
+
+    void* addr = shmat(shmid, NULL, 0);
+    if (addr == (void*) -1) {
+        LOG(LOG_ERROR, "shmem", "Could not attach to key=%d shmid=%d\n",
+            key, shmid);
+        return false;
+    }
+
+    mAddr = addr;
+
+    /* done with shmem, attach to associated semaphore */
+    if (!mSem.attach(key)) {
+        LOG(LOG_ERROR, "shmem",
+            "Failed to attach to semaphore for Shmem (key=%d)\n", key);
+        return false;
+    }
+
+    return true;
+}
+
+/*
+ * Get address.
+ */
+void* Shmem::getAddr(void)
+{
+    assert(mAddr != NULL);
+    return mAddr;
+}
+
+/*
+ * Return the length of the segment.
+ *
+ * Returns -1 on failure.
+ */
+long Shmem::getLength(void)
+{
+    if (mLength >= 0)
+        return mLength;
+
+    assert(mHandle != kInvalidHandle);
+
+    struct shmid_ds shmids;
+    int cc;
+
+    cc = shmctl((int) mHandle, IPC_STAT, &shmids);
+    if (cc != 0) {
+        LOG(LOG_ERROR, "shmem", "Could not IPC_STAT shmid=%ld\n", mHandle);
+        return -1;
+    }
+    mLength = shmids.shm_segsz;     // save a copy to avoid future lookups
+
+    return mLength;
+}
+
+
+#elif defined(HAVE_WIN32_IPC) // ---------------------------------------------
+
+/*
+ * Win32 shared memory implementation.
+ *
+ * Shared memory is implemented as an "anonymous" file mapping, using the
+ * memory-mapped I/O interfaces.
+ */
+
+static const char* kShmemStr = "android-shmem-";
+
+/*
+ * Constructor.  Just set up the fields.
+ */
+Shmem::Shmem(void)
+    : mHandle((unsigned long) INVALID_HANDLE_VALUE),
+      mAddr(NULL), mLength(-1), mCreator(false), mKey(-1)
+{
+}
+
+/*
+ * Destructor.  The Win32 API doesn't require a distinction between
+ * the "creator" and other mappers.
+ */
+Shmem::~Shmem(void)
+{
+    LOG(LOG_DEBUG, "shmem", "~Shmem(handle=%ld creator=%d)",
+        mHandle, mCreator);
+
+    if (mAddr != NULL)
+        UnmapViewOfFile(mAddr);
+    if (mHandle != (unsigned long) INVALID_HANDLE_VALUE)
+        CloseHandle((HANDLE) mHandle);
+}
+
+/*
+ * Create the segment and map it.
+ */
+bool Shmem::create(int key, long size, bool deleteExisting)
+{
+    char keyBuf[64];
+    HANDLE hMapFile;
+
+    snprintf(keyBuf, sizeof(keyBuf), "%s%d", kShmemStr, key);
+
+    hMapFile = CreateFileMapping(
+                INVALID_HANDLE_VALUE,       // use paging file, not actual file
+                NULL,                       // default security
+                PAGE_READWRITE,             // read/write access
+                0,                          // max size; no need to cap
+                size,                       // min size
+                keyBuf);                    // mapping name
+    if (hMapFile == NULL || hMapFile == INVALID_HANDLE_VALUE) {
+        LOG(LOG_ERROR, "shmem",
+            "Could not create mapping object '%s' (err=%ld)\n",
+            keyBuf, GetLastError());
+        return false;
+    }
+
+    mHandle = (unsigned long) hMapFile;
+    mCreator = true;
+    mKey = key;
+
+    mAddr = MapViewOfFile(
+                hMapFile,                   // handle to map object
+                FILE_MAP_ALL_ACCESS,        // read/write
+                0,                          // offset (hi)
+                0,                          // offset (lo)
+                size);                      // #of bytes to map
+    if (mAddr == NULL) {
+        LOG(LOG_ERROR, "shmem", "Could not map shared area (err=%ld)\n",
+            GetLastError());
+        return false;
+    }
+    mLength = size;
+
+    /* done with shmem, create the associated semaphore */
+    if (!mSem.create(key, 1, true)) {
+        LOG(LOG_ERROR, "shmem",
+            "Failed creating semaphore for Shmem (key=%d)\n", key);
+        return false;
+    }
+
+    return true;
+}
+
+/*
+ * Attach ourselves to an existing segment.
+ */
+bool Shmem::attach(int key)
+{
+    char keyBuf[64];
+    HANDLE hMapFile;
+
+    snprintf(keyBuf, sizeof(keyBuf), "%s%d", kShmemStr, key);
+
+    hMapFile = OpenFileMapping(
+                FILE_MAP_ALL_ACCESS,        // read/write
+                FALSE,                      // don't let kids inherit handle
+                keyBuf);                    // mapping name
+    if (hMapFile == NULL) {
+        LOG(LOG_ERROR, "shmem",
+            "Could not open mapping object '%s' (err=%ld)\n",
+            keyBuf, GetLastError());
+        return false;
+    }
+
+    mHandle = (unsigned long) hMapFile;
+    assert(mCreator == false);
+    mKey = key;
+
+    mAddr = MapViewOfFile(
+                hMapFile,                   // handle to map object
+                FILE_MAP_ALL_ACCESS,        // read/write
+                0,                          // offset (hi)
+                0,                          // offset (lo)
+                0);                        // #of bytes to map
+    if (mAddr == NULL) {
+        LOG(LOG_ERROR, "shmem", "Could not map shared area (err=%ld)\n",
+            GetLastError());
+        return false;
+    }
+
+    /* done with shmem, attach to associated semaphore */
+    if (!mSem.attach(key)) {
+        LOG(LOG_ERROR, "shmem",
+            "Failed to attach to semaphore for Shmem (key=%d)\n", key);
+        return false;
+    }
+
+    return true;
+}
+
+/*
+ * Get address.
+ */
+void* Shmem::getAddr(void)
+{
+    assert(mAddr != NULL);
+    return mAddr;
+}
+
+/*
+ * Get the length of the segment.
+ */
+long Shmem::getLength(void)
+{
+    SIZE_T size;
+    MEMORY_BASIC_INFORMATION mbInfo;
+
+    if (mLength >= 0)
+        return mLength;
+
+    assert(mAddr != NULL);
+
+    size = VirtualQuery(mAddr, &mbInfo, sizeof(mbInfo));
+    if (size == 0) {
+        LOG(LOG_WARN, "shmem", "VirtualQuery returned no data\n");
+        return -1;
+    }
+
+    mLength = mbInfo.RegionSize;
+    return mLength;
+}
+
+#endif // --------------------------------------------------------------------
+
+/*
+ * Semaphore operations.
+ */
+void Shmem::lock(void)
+{
+    mSem.acquire();
+}
+void Shmem::unlock(void)
+{
+    mSem.release();
+}
+bool Shmem::tryLock(void)
+{
+    return mSem.tryAcquire();
+}
+