예제 #1
0
static bool
createMarkStack(GcMarkStack *stack)
{
    const Object **limit;
    size_t size;
    int fd;

    /* Create a stack big enough for the worst possible case,
     * where the heap is perfectly full of the smallest object.
     * TODO: be better about memory usage; use a smaller stack with
     *       overflow detection and recovery.
     */
    size = dvmHeapSourceGetIdealFootprint() /
            (sizeof(Object) + HEAP_SOURCE_CHUNK_OVERHEAD);
    size = ALIGN_UP_TO_PAGE_SIZE(size);
    fd = ashmem_create_region("dalvik-heap-markstack", size);
    if (fd < 0) {
        LOGE_GC("Could not create %d-byte ashmem mark stack\n", size);
        return false;
    }
    limit = (const Object **)mmap(NULL, size, PROT_READ | PROT_WRITE,
            MAP_PRIVATE, fd, 0);
    close(fd);
    if (limit == MAP_FAILED) {
        LOGE_GC("Could not mmap %d-byte ashmem mark stack\n", size);
        return false;
    }

    memset(stack, 0, sizeof(*stack));
    stack->limit = limit;
    stack->base = (const Object **)((uintptr_t)limit + size);
    stack->top = stack->base;

    return true;
}
static jint android_util_MemoryIntArray_create(JNIEnv* env, jobject clazz, jstring name,
        jint size)
{
    if (name == NULL) {
        jniThrowException(env, "java/io/IOException", "bad name");
        return -1;
    }

    if (size <= 0) {
        jniThrowException(env, "java/io/IOException", "bad size");
        return -1;
    }

    const char* nameStr = env->GetStringUTFChars(name, NULL);
    const int ashmemSize = sizeof(std::atomic_int) * size;
    int fd = ashmem_create_region(nameStr, ashmemSize);
    env->ReleaseStringUTFChars(name, nameStr);

    if (fd < 0) {
        jniThrowException(env, "java/io/IOException", "ashmem creation failed");
        return -1;
    }

    int setProtResult = ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE);
    if (setProtResult < 0) {
        jniThrowException(env, "java/io/IOException", "cannot set ashmem prot mode");
        return -1;
    }

    return fd;
}
예제 #3
0
파일: MemArena.cpp 프로젝트: Falaina/ppsspp
void MemArena::GrabLowMemSpace(size_t size)
{
#ifdef _WIN32
	hMemoryMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, (DWORD)(size), NULL);
  GetSystemInfo(&sysInfo);
#elif ANDROID
	// Use ashmem so we don't have to allocate a file on disk!
	fd = ashmem_create_region("PPSSPP_RAM", size);
	// Note that it appears that ashmem is pinned by default, so no need to pin.
	if (fd < 0)
	{
		ERROR_LOG(MEMMAP, "Failed to grab ashmem space of size: %08x  errno: %d", (int)size, (int)(errno));
		return;
	}
#else
	mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
	fd = open(ram_temp_file.c_str(), O_RDWR | O_CREAT, mode);
	if (fd < 0)
	{
		ERROR_LOG(MEMMAP, "Failed to grab memory space as a file: %s of size: %08x  errno: %d", ram_temp_file.c_str(), (int)size, (int)(errno));
		return;
	}
	// delete immediately, we keep the fd so it still lives
	unlink(ram_temp_file.c_str());
	if (ftruncate(fd, size) != 0)
	{
		ERROR_LOG(MEMMAP, "Failed to ftruncate %d to size %08x", (int)fd, (int)size);
	}
	return;
#endif
}
static int init_workspace(workspace *w, size_t size)
{
    void *data;
    int fd;

    fd = ashmem_create_region("system_properties", size);
    if(fd < 0)
        return -1;

    data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if(data == MAP_FAILED)
        goto out;

    /* allow the wolves we share with to do nothing but read */
    ashmem_set_prot_region(fd, PROT_READ);

    w->data = data;
    w->size = size;
    w->fd = fd;

    return 0;

out:
    close(fd);
    return -1;
}
예제 #5
0
int createNewAshmem(const char *name, int size, u8 **addr)
{
    int fd = ashmem_create_region(name, size + sizeof(u32));

    if(fd >= 0)
    {
        LOGI("create ashmem name:%s size:%d fd:%d success!", name, size, fd);

        t_ashmBlock *ashm = mmap(NULL, size, PROT_READ | PROT_WRITE,
                                 MAP_SHARED, fd, 0);

        if(ashm != NULL)
        {
            t_ashmNode *newAshmNode = malloc(sizeof(t_ashmNode));

            if(newAshmNode != NULL)
            {
                ashm->ashmStat = 0;

                if(addr != NULL)
                {
                    *addr = ashm->data;
                }

                newAshmNode->ashmem = ashm;
                newAshmNode->fd = fd;
                strncpy(newAshmNode->name, name, ASHM_NAME_SIZE);
                newAshmNode->next = NULL;
                newAshmNode->size = size;

                if(ashmemChainHead == NULL)
                {
                    ashmemChainHead = newAshmNode;
                }

                if(ashmemChainTail != NULL)
                {
                    ashmemChainTail->next = newAshmNode;
                }

                ashmemChainTail = newAshmNode;


                LOGI("ashmem mmap %d to watchdog process success!", (u32)ashm);

                if(strcmp(name, "ashmTest") == 0)
                {
                    int i;

                    for(i = 0; i < 8; i++)
                    {
                        ashm->data[i] = i;
                    }
                }
            }
        }
    }

    return fd;
}
예제 #6
0
void shell_main(){

    dlopen_t dlopen_f = (dlopen_t)getProcAddr(NULL,"dlopen");
    dlsym_t dlsym_f = (dlsym_t)getProcAddr(NULL,"dlsym");

    const char *so_name = "/data/local/tmp/testso.so";
    char *code = (char*)get_so_buffer(so_name); 
    int ashmem_len = *(int*)code;
    int fd_memory = ashmem_create_region("shmem", ashmem_len);
    ashmem_pin_region(fd_memory, 0, 0);
    uint8_t *shm = (uint8_t*)mmap(NULL, ashmem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd_memory, 0);
    printf("first map address is %p\n",shm);
    memcpy(shm,code,ashmem_len);
    free(code);
    //ashmem_unpin_region(fd_memory, 0, 0);

    int pos[32]={12,2,12,fd_memory};
    //shellcode(dlopen_f,pos);
    uint32_t libcbase = (uint32_t)getModuleBase("libc.so");
    uint32_t mprotect_address = (uint32_t)getProcAddr("libc.so","mprotect");
    uint32_t len = 0;
    void *buffer = get_shellcode(&len);
    uint32_t ropData[29]={libcbase+0x15056+1,1+libcbase+0x4c8ee,0xdeaddead,0xdeaddead,(uint32_t)buffer&0xfffff000,4096,0x7,(uint32_t)mprotect_address,(uint32_t)dlopen_f,(uint32_t)pos,2,(uint32_t)buffer+1};
    //uint32_t ropData[29]={libcbase+0x15056+1,1+libcbase+0x4c8ee,0xdeaddead,0xdeaddead,(uint32_t)buffer&0xfffff000,4096,0x7,(uint32_t)mprotect_address,(uint32_t)dlopen_f,1,2,(uint32_t)shellcode};
    asmm_test((uint32_t)ropData);
    free(buffer);
    exit(-1);
}
static int createAshmemRegionWithData(JNIEnv* env, const void* data, size_t length) {
    int error = 0;
    int fd = ashmem_create_region(NULL, length);
    if (fd < 0) {
        error = errno;
        ALOGE("ashmem_create_region failed: %s", strerror(error));
    } else {
        if (length > 0) {
            void* ptr = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
            if (ptr == MAP_FAILED) {
                error = errno;
                ALOGE("mmap failed: %s", strerror(error));
            } else {
                memcpy(ptr, data, length);
                munmap(ptr, length);
            }
        }

        if (!error) {
            if (ashmem_set_prot_region(fd, PROT_READ) < 0) {
                error = errno;
                ALOGE("ashmem_set_prot_region failed: %s", strerror(errno));
            } else {
                return fd;
            }
        }

        close(fd);
    }

    jniThrowIOException(env, error);
    return -1;
}
예제 #8
0
void MemArena::GrabLowMemSpace(size_t size) {
	// Use ashmem so we don't have to allocate a file on disk!
	fd = ashmem_create_region("PPSSPP_RAM", size);
	// Note that it appears that ashmem is pinned by default, so no need to pin.
	if (fd < 0) {
		ERROR_LOG(MEMMAP, "Failed to grab ashmem space of size: %08x  errno: %d", (int)size, (int)(errno));
		return;
	}
}
Overlay::Overlay(uint32_t width, uint32_t height, Format format, QueueBufferHook queueBufferHook, void *data) :
    mQueueBufferHook(queueBufferHook),
    mHookData(data),
    mNumFreeBuffers(0),
    mStatus(NO_INIT),
    mWidth(width),
    mHeight(height),
    mFormat(format)
{
    ALOGD("%s: Init overlay, format=%d", __FUNCTION__, format);

    unsigned int mapped = 0;
    int bpp = getBppFromFormat(format);
    /* round up to next multiple of 8 */
    if (bpp & 7) {
        bpp = (bpp & ~7) + 8;
    }

    const int requiredMem = width * height * bpp;
    const int bufferSize = (requiredMem + PAGE_SIZE - 1) & (~(PAGE_SIZE - 1));

    int fd = ashmem_create_region("Overlay_buffer_region", NUM_BUFFERS * bufferSize);
    if (fd < 0) {
        ALOGE("%s: Cannot create ashmem region", __FUNCTION__);
        return;
    }

    ALOGV("%s: allocated ashmem region for %d buffers of size %d", __FUNCTION__, NUM_BUFFERS, bufferSize);

    for (uint32_t i = 0; i < NUM_BUFFERS; i++) {
        mBuffers[i].fd = fd;
        mBuffers[i].length = bufferSize;
        mBuffers[i].offset = bufferSize * i;
        ALOGV("%s: mBuffers[%d].offset = 0x%x", __FUNCTION__, i, mBuffers[i].offset);
        mBuffers[i].ptr = mmap(NULL, bufferSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, bufferSize * i);
        if (mBuffers[i].ptr == MAP_FAILED) {
            ALOGE("%s: Failed to mmap buffer %d", __FUNCTION__, i);
            mBuffers[i].ptr = NULL;
            continue;
        }
        mQueued[i] = false;
        mapped++;
    }

    pthread_mutex_init(&mQueueMutex, NULL);

    ALOGD("%s: Init overlay complete, %u mapped", __FUNCTION__, mapped);

    mStatus = NO_ERROR;
}
예제 #10
0
    virtual bool allocPixelRef(SkBitmap* bm, SkColorTable* ct) {
        const size_t size = roundToPageSize(bm->getSize());
        int fd = fRec->fFD;
        void* addr = fRec->fAddr;

        SkASSERT(!fRec->fPinned);

        if (-1 == fd) {
            SkASSERT(NULL == addr);
            SkASSERT(0 == fRec->fSize);

            fd = ashmem_create_region(fName, size);
#ifdef DUMP_ASHMEM_LIFECYCLE
            SkDebugf("=== ashmem_create_region %s size=%d fd=%d\n", fName, size, fd);
#endif
            if (-1 == fd) {
                SkDebugf("------- imageref_ashmem create failed <%s> %d\n",
                         fName, size);
                return false;
            }

            int err = ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE);
            if (err) {
                SkDebugf("------ ashmem_set_prot_region(%d) failed %d\n",
                         fd, err);
                close(fd);
                return false;
            }

            addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
            if (-1 == (long)addr) {
                SkDebugf("---------- mmap failed for imageref_ashmem size=%d\n",
                         size);
                close(fd);
                return false;
            }

            fRec->fFD = fd;
            fRec->fAddr = addr;
            fRec->fSize = size;
        } else {
            SkASSERT(addr);
            SkASSERT(size == fRec->fSize);
            (void)ashmem_pin_region(fd, 0, 0);
        }

        bm->setPixels(addr, ct);
        fRec->fPinned = true;
        return true;
    }
예제 #11
0
int cras_shm_open_rw (const char *name, size_t size)
{
	int fd;

	/* Eliminate the / in the shm_name. */
	if (name[0] == '/')
		name++;
	fd = ashmem_create_region(name, size);
	if (fd < 0) {
		fd = -errno;
		syslog(LOG_ERR, "failed to ashmem_create_region %s: %s\n",
		       name, strerror(-fd));
	}
	return fd;
}
예제 #12
0
MemoryHeapBase::MemoryHeapBase(size_t size, uint32_t flags, char const * name)
    : mFD(-1), mSize(0), mBase(MAP_FAILED), mFlags(flags),
      mDevice(0), mNeedUnmap(false), mOffset(0)
{
    const size_t pagesize = getpagesize();
    size = ((size + pagesize-1) & ~(pagesize-1));
    int fd = ashmem_create_region(name == NULL ? "MemoryHeapBase" : name, size);
    ALOGE_IF(fd<0, "error creating ashmem region: %s", strerror(errno));
    if (fd >= 0) {
        if (mapfd(fd, size) == NO_ERROR) {
            if (flags & READ_ONLY) {
                ashmem_set_prot_region(fd, PROT_READ);
            }
        }
    }
}
예제 #13
0
get_ashmem(backing_store_ptr info, long total_bytes_needed)
{
  char path[1024];
  snprintf(path, 1023, "%d.tmp.ashmem", getpid());
  int fd = ashmem_create_region(path, total_bytes_needed);
  if (fd == -1) {
      return -1;
  }
  int err = ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE);
  if (err) {
      return -1;
  }
  info->addr = mmap(NULL, total_bytes_needed, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
  info->size = total_bytes_needed;
  info->temp_file = fd;
  return fd;
}
예제 #14
0
mspace create_contiguous_mspace_with_name(size_t starting_capacity,
    size_t max_capacity, int locked, char const *name) {
  int fd, ret;
  char buf[ASHMEM_NAME_LEN] = "mspace";
  void *base;
  unsigned int pagesize;
  mstate m;

  if (starting_capacity > max_capacity)
    return (mspace)0;

  init_mparams();
  pagesize = PAGESIZE;

  /* Create the anonymous memory that will back the mspace.
   * This reserves all of the virtual address space we could
   * ever need.  Physical pages will be mapped as the memory
   * is touched.
   *
   * Align max_capacity to a whole page.
   */
  max_capacity = (size_t)ALIGN_UP(max_capacity, pagesize);

  if (name)
    snprintf(buf, sizeof(buf), "mspace/%s", name);
  fd = ashmem_create_region(buf, max_capacity);
  if (fd < 0)
    return (mspace)0;

  base = mmap(NULL, max_capacity, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
  close(fd);
  if (base == MAP_FAILED)
    return (mspace)0;

  /* Make sure that base is at the beginning of a page.
   */
  assert(((uintptr_t)base & (pagesize-1)) == 0);

  m = create_contiguous_mspace_with_base(starting_capacity, max_capacity,
                                         locked, base);
  if (m == 0) {
    munmap(base, max_capacity);
  }
  return m;
}
예제 #15
0
status_t CursorWindow::create(const String8& name, size_t size, CursorWindow** outCursorWindow) {
    String8 ashmemName("CursorWindow: ");
    ashmemName.append(name);

    status_t result;
    int ashmemFd = ashmem_create_region(ashmemName.string(), size);
    if (ashmemFd < 0) {
    	ALOG(LOG_ERROR,LOG_TAG,"CursorWindow::create, ashmem_create_region return errno = %d",errno);
        result = -errno;
    } else {
        result = ashmem_set_prot_region(ashmemFd, PROT_READ | PROT_WRITE);
        if (result >= 0) {
            void* data = ::mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, ashmemFd, 0);
            if (data == MAP_FAILED) {
            	ALOG(LOG_ERROR,LOG_TAG,"CursorWindow::create, mmap return errno = %d",errno);
                result = -errno;
            } else {
                result = ashmem_set_prot_region(ashmemFd, PROT_READ);
                if (result >= 0) {
                    CursorWindow* window = new CursorWindow(name, ashmemFd,
                            data, size, false /*readOnly*/);
                    result = window->clear();
                    if (!result) {
                        LOG_WINDOW("Created new CursorWindow: freeOffset=%d, "
                                "numRows=%d, numColumns=%d, mSize=%d, mData=%p",
                                window->mHeader->freeOffset,
                                window->mHeader->numRows,
                                window->mHeader->numColumns,
                                window->mSize, window->mData);
                        *outCursorWindow = window;
                        return OK;
                    }
                    ALOG(LOG_ERROR,LOG_TAG,"CursorWindow::create, window->clear return errno = %d",errno);
                    delete window;
                } else {
                    ALOG(LOG_ERROR,LOG_TAG,"CursorWindow::create, ashmeme_set_prot_region return errno = %d",errno);	
                }
            }
            ::munmap(data, size);
        }
        ::close(ashmemFd);
    }
    *outCursorWindow = NULL;
    return result;
}
예제 #16
0
파일: gpu.cpp 프로젝트: AOKP/hardware_msm7k
int gpu_context_t::alloc_ashmem_buffer(size_t size, unsigned int postfix, void** pBase,
            int* pOffset, int* pFd)
{
    int err = 0;
    int fd = -1;
    void* base = 0;
    int offset = 0;

    char name[ASHMEM_NAME_LEN];
    snprintf(name, ASHMEM_NAME_LEN, "gralloc-buffer-%x", postfix);
    int prot = PROT_READ | PROT_WRITE;
    fd = ashmem_create_region(name, size);
    if (fd < 0) {
        LOGE("couldn't create ashmem (%s)", strerror(errno));
        err = -errno;
    } else {
        if (ashmem_set_prot_region(fd, prot) < 0) {
            LOGE("ashmem_set_prot_region(fd=%d, prot=%x) failed (%s)",
                 fd, prot, strerror(errno));
            close(fd);
            err = -errno;
        } else {
            base = mmap(0, size, prot, MAP_SHARED|MAP_POPULATE|MAP_LOCKED, fd, 0);
            if (base == MAP_FAILED) {
                LOGE("alloc mmap(fd=%d, size=%d, prot=%x) failed (%s)",
                     fd, size, prot, strerror(errno));
                close(fd);
                err = -errno;
            } else {
                memset((char*)base + offset, 0, size);
            }
        }
    }
    if(err == 0) {
        *pFd = fd;
        *pBase = base;
        *pOffset = offset;
#ifdef HOST
        if (ioctl(fd, ASHMEM_CACHE_INV_RANGE, NULL)) {
            LOGE("ASHMEM_CACHE_INV_RANGE failed fd = %d", fd);
        }
#endif
    }
    return err;
}
예제 #17
0
파일: test.c 프로젝트: junzhe/ashmem_lib
int main(){
	char dum[] = "test";

	int id;
	char * addr;

	id = ashmem_create_region(dum, 40960);

	printf("id test %d\n", id);

	addr = (char *) ashmem_mmap(NULL, 10, 0, 0, id, 0);

	*addr = 'c';

	printf("%c\n", *addr);

	return 0;
}
static jobject android_os_MemoryFile_open(JNIEnv* env, jobject clazz, jstring name, jint length)
{
    const char* namestr = (name ? env->GetStringUTFChars(name, NULL) : NULL);

    // round up length to page boundary
    length = (((length - 1) / getpagesize()) + 1) * getpagesize();
    int result = ashmem_create_region(namestr, length);

    if (name)
        env->ReleaseStringUTFChars(name, namestr);

    if (result < 0) {
        jniThrowException(env, "java/io/IOException", "ashmem_create_region failed");
        return NULL;
    }

    return jniCreateFileDescriptor(env, result);
}
예제 #19
0
파일: Misc.cpp 프로젝트: acpaluri/591_Comet
/*
 *  Allocates a memory region using ashmem and mmap, initialized to
 *  zero.  Actual allocation rounded up to page multiple.  Returns
 *  NULL on failure.
 */
void *dvmAllocRegion(size_t byteCount, int prot, const char *name) {
    void *base;
    int fd, ret;

    byteCount = ALIGN_UP_TO_PAGE_SIZE(byteCount);
    fd = ashmem_create_region(name, byteCount);
    if (fd == -1) {
        return NULL;
    }
    base = mmap(NULL, byteCount, prot, MAP_PRIVATE, fd, 0);
    ret = close(fd);
    if (base == MAP_FAILED) {
        return NULL;
    }
    if (ret == -1) {
        return NULL;
    }
    return base;
}
예제 #20
0
/*
 * Initialize a HeapBitmap so that it points to a bitmap large
 * enough to cover a heap at <base> of <maxSize> bytes, where
 * objects are guaranteed to be HB_OBJECT_ALIGNMENT-aligned.
 */
bool
dvmHeapBitmapInit(HeapBitmap *hb, const void *base, size_t maxSize,
        const char *name)
{
    void *bits;
    size_t bitsLen;
    size_t allocLen;
    int fd;
    char nameBuf[ASHMEM_NAME_LEN] = HB_ASHMEM_NAME;

    assert(hb != NULL);

    bitsLen = HB_OFFSET_TO_INDEX(maxSize) * sizeof(*hb->bits);
    allocLen = ALIGN_UP_TO_PAGE_SIZE(bitsLen);   // required by ashmem

    if (name != NULL) {
        snprintf(nameBuf, sizeof(nameBuf), HB_ASHMEM_NAME "/%s", name);
    }
    fd = ashmem_create_region(nameBuf, allocLen);
    if (fd < 0) {
        LOGE("Could not create %zu-byte ashmem region \"%s\" to cover "
                "%zu-byte heap (%d)\n",
                allocLen, nameBuf, maxSize, fd);
        return false;
    }

    bits = mmap(NULL, bitsLen, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
    close(fd);
    if (bits == MAP_FAILED) {
        LOGE("Could not mmap %d-byte ashmem region \"%s\"\n",
                bitsLen, nameBuf);
        return false;
    }

    memset(hb, 0, sizeof(*hb));
    hb->bits = bits;
    hb->bitsLen = bitsLen;
    hb->base = (uintptr_t)base;
    hb->max = hb->base - 1;

    return true;
}
예제 #21
0
static mspace getMspace()
{
    if (gExecutableStore == NULL) {
        int fd = ashmem_create_region("CodeFlinger code cache",
                                      kMaxCodeCacheCapacity);
        LOG_ALWAYS_FATAL_IF(fd < 0,
                            "Creating code cache, ashmem_create_region "
                            "failed with error '%s'", strerror(errno));
        gExecutableStore = mmap(NULL, kMaxCodeCacheCapacity,
                                PROT_READ | PROT_WRITE | PROT_EXEC,
                                MAP_PRIVATE, fd, 0);
        LOG_ALWAYS_FATAL_IF(gExecutableStore == MAP_FAILED,
                            "Creating code cache, mmap failed with error "
                            "'%s'", strerror(errno));
        close(fd);
        gMspace = create_mspace_with_base(gExecutableStore, kMaxCodeCacheCapacity,
                                          /*locked=*/ false);
        mspace_set_footprint_limit(gMspace, kMaxCodeCacheCapacity);
    }
    return gMspace;
}
OMX_U8* OMXVideoDecoderAVCSecure::MemAllocDataBuffer(OMX_U32 nSizeBytes) {

    ALOGW_IF(nSizeBytes != INPORT_BUFFER_SIZE,
        "%s: size of memory to allocate is %" PRIu32 ", but will allocate %zu",
        __FUNCTION__, nSizeBytes, sizeof(ProtectedDataBuffer));
    
    if (mNumInportBuffers >= INPORT_ACTUAL_BUFFER_COUNT)
    {
        ALOGE("%s: cannot allocate buffer: number of inport buffers is %u, which is already at maximum",
            __FUNCTION__, mNumInportBuffers);
        return NULL;
    }


    int fd = ashmem_create_region("protectd-content-buffer", sizeof(ProtectedDataBuffer));
    if(fd < 0) {
        ALOGE("Unable to create ashmem region");
        return NULL;
    }

    native_handle_t *native = native_handle_create(1, 2);

    native->data[0] = fd;
    ProtectedDataBuffer *pBuffer =(ProtectedDataBuffer *) mmap(NULL, sizeof(ProtectedDataBuffer), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (pBuffer == MAP_FAILED) {
        ALOGE("%s: mmap failed", __FUNCTION__);
        return NULL;
    }
    native->data[1] = (int) pBuffer;
    // Use a random value as the buffer id
    native->data[2] = rand();
    ++mNumInportBuffers;

    Init_ProtectedDataBuffer(pBuffer);
    
    pBuffer->size = INPORT_BUFFER_SIZE;

    ALOGV("Allocating native=[%p] buffer = %#x, data = %#x data_end=  %#x size=%d",(OMX_U8 *)native,(uint32_t)pBuffer, (uint32_t)pBuffer->data, (uint32_t)pBuffer->data + sizeof(ProtectedDataBuffer) ,sizeof(ProtectedDataBuffer));
    return (OMX_U8 *) native;
}
예제 #23
0
void MemArena::GrabLowMemSpace(size_t size)
{
#ifdef _WIN32
#ifndef _XBOX
    hMemoryMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, (DWORD)(size), NULL);
    GetSystemInfo(&sysInfo);
#endif
#elif defined(ANDROID)
    // Use ashmem so we don't have to allocate a file on disk!
    fd = ashmem_create_region("PPSSPP_RAM", size);
    // Note that it appears that ashmem is pinned by default, so no need to pin.
    if (fd < 0)
    {
        ERROR_LOG(MEMMAP, "Failed to grab ashmem space of size: %08x  errno: %d", (int)size, (int)(errno));
        return;
    }
#else
    // Try to find a non-existing filename for our shared memory.
    // In most cases the first one will be available, but it's nicer to search
    // a bit more.
    for (int i = 0; i < 10000; i++)
    {
        std::string file_name = Common::StringFromFormat("/citramem.%d", i);
        fd = shm_open(file_name.c_str(), O_RDWR | O_CREAT | O_EXCL, 0600);
        if (fd != -1)
        {
            shm_unlink(file_name.c_str());
            break;
        }
        else if (errno != EEXIST)
        {
            ERROR_LOG(MEMMAP, "shm_open failed: %s", strerror(errno));
            return;
        }
    }
    if (ftruncate(fd, size) < 0)
        ERROR_LOG(MEMMAP, "Failed to allocate low memory space");
#endif
}
예제 #24
0
/*
 * A helper for addNewHeap(). Remap the new heap so that it will have
 * a separate ashmem region with possibly a different name, etc. In
 * practice, this is used to give the app heap a separate ashmem
 * region from the zygote heap's.
 */
static bool remapNewHeap(HeapSource* hs, Heap* newHeap)
{
    char* newHeapBase = newHeap->base;
    size_t rem_size = hs->heapBase + hs->heapLength - newHeapBase;
    munmap(newHeapBase, rem_size);
    int fd = ashmem_create_region("dalvik-heap", rem_size);
    if (fd == -1) {
        ALOGE("Unable to create an ashmem region for the new heap");
        return false;
    }
    void* addr = mmap(newHeapBase, rem_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, fd, 0);
    int ret = close(fd);
    if (addr == MAP_FAILED) {
        ALOGE("Unable to map an ashmem region for the new heap");
        return false;
    }
    if (ret == -1) {
        ALOGE("Unable to close fd for the ashmem region for the new heap");
        munmap(newHeapBase, rem_size);
        return false;
    }
    return true;
}
예제 #25
0
/*
 * Create a new linear allocation block.
 */
LinearAllocHdr* dvmLinearAllocCreate(Object* classLoader)
{
#ifdef DISABLE_LINEAR_ALLOC
    return (LinearAllocHdr*) 0x12345;
#endif
    LinearAllocHdr* pHdr;

    pHdr = (LinearAllocHdr*) malloc(sizeof(*pHdr));


    /*
     * "curOffset" points to the location of the next pre-block header,
     * which means we have to advance to the next BLOCK_ALIGN address and
     * back up.
     *
     * Note we leave the first page empty (see below), and start the
     * first entry on the second page at an offset that ensures the next
     * chunk of data will be properly aligned.
     */
    assert(BLOCK_ALIGN >= HEADER_EXTRA);
    pHdr->curOffset = pHdr->firstOffset = (BLOCK_ALIGN-HEADER_EXTRA) + PAGESIZE;
    pHdr->mapLength = DEFAULT_MAX_LENGTH;

#ifdef USE_ASHMEM
    int fd;

    fd = ashmem_create_region("dalvik-LinearAlloc", DEFAULT_MAX_LENGTH);
    if (fd < 0) {
        LOGE("ashmem LinearAlloc failed %s", strerror(errno));
        free(pHdr);
        return NULL;
    }

    pHdr->mapAddr = mmap(NULL, pHdr->mapLength, PROT_READ | PROT_WRITE,
        MAP_PRIVATE, fd, 0);
    if (pHdr->mapAddr == MAP_FAILED) {
        LOGE("LinearAlloc mmap(%d) failed: %s\n", pHdr->mapLength,
            strerror(errno));
        free(pHdr);
        close(fd);
        return NULL;
    }

    close(fd);
#else /*USE_ASHMEM*/
    // MAP_ANON is listed as "deprecated" on Linux,
    // but MAP_ANONYMOUS is not defined under Mac OS X.
    pHdr->mapAddr = mmap(NULL, pHdr->mapLength, PROT_READ | PROT_WRITE,
        MAP_PRIVATE | MAP_ANON, -1, 0);
    if (pHdr->mapAddr == MAP_FAILED) {
        LOGE("LinearAlloc mmap(%d) failed: %s\n", pHdr->mapLength,
            strerror(errno));
        free(pHdr);
        return NULL;
    }
#endif /*USE_ASHMEM*/

    /* region expected to begin on a page boundary */
    assert(((int) pHdr->mapAddr & (PAGESIZE-1)) == 0);

    /* the system should initialize newly-mapped memory to zero */
    assert(*(u4*) (pHdr->mapAddr + pHdr->curOffset) == 0);

    /*
     * Disable access to all except starting page.  We will enable pages
     * as we use them.  This helps prevent bad pointers from working.  The
     * pages start out PROT_NONE, become read/write while we access them,
     * then go to read-only after we finish our changes.
     *
     * We have to make the first page readable because we have 4 pad bytes,
     * followed by 4 length bytes, giving an initial offset of 8.  The
     * generic code below assumes that there could have been a previous
     * allocation that wrote into those 4 pad bytes, therefore the page
     * must have been marked readable by the previous allocation.
     *
     * We insert an extra page in here to force a break in the memory map
     * so we can see ourselves more easily in "showmap".  Otherwise this
     * stuff blends into the neighboring pages.  [TODO: do we still need
     * the extra page now that we have ashmem?]
     */
    if (mprotect(pHdr->mapAddr, pHdr->mapLength, PROT_NONE) != 0) {
        LOGW("LinearAlloc init mprotect failed: %s\n", strerror(errno));
        free(pHdr);
        return NULL;
    }
    if (mprotect(pHdr->mapAddr + PAGESIZE, PAGESIZE,
            ENFORCE_READ_ONLY ? PROT_READ : PROT_READ|PROT_WRITE) != 0)
    {
        LOGW("LinearAlloc init mprotect #2 failed: %s\n", strerror(errno));
        free(pHdr);
        return NULL;
    }

    if (ENFORCE_READ_ONLY) {
        /* allocate the per-page ref count */
        int numPages = (pHdr->mapLength+PAGESIZE-1) / PAGESIZE;
        pHdr->writeRefCount = calloc(numPages, sizeof(short));
        if (pHdr->writeRefCount == NULL) {
            free(pHdr);
            return NULL;
        }
    }

    dvmInitMutex(&pHdr->lock);

    LOGV("LinearAlloc: created region at %p-%p\n",
        pHdr->mapAddr, pHdr->mapAddr + pHdr->mapLength-1);

    return pHdr;
}
예제 #26
0
//
// gralloc device functions (alloc interface)
//
static int gralloc_alloc(alloc_device_t* dev,
                         int w, int h, int format, int usage,
                         buffer_handle_t* pHandle, int* pStride)
{
    D("gralloc_alloc w=%d h=%d usage=0x%x\n", w, h, usage);

    gralloc_device_t *grdev = (gralloc_device_t *)dev;
    if (!grdev || !pHandle || !pStride) {
        ALOGE("gralloc_alloc: Bad inputs (grdev: %p, pHandle: %p, pStride: %p",
                grdev, pHandle, pStride);
        return -EINVAL;
    }

    //
    // Note: in screen capture mode, both sw_write and hw_write will be on
    // and this is a valid usage
    //
    bool sw_write = (0 != (usage & GRALLOC_USAGE_SW_WRITE_MASK));
    bool hw_write = (usage & GRALLOC_USAGE_HW_RENDER);
    bool sw_read = (0 != (usage & GRALLOC_USAGE_SW_READ_MASK));
    bool hw_cam_write = usage & GRALLOC_USAGE_HW_CAMERA_WRITE;
    bool hw_cam_read = usage & GRALLOC_USAGE_HW_CAMERA_READ;
    bool hw_vid_enc_read = usage & GRALLOC_USAGE_HW_VIDEO_ENCODER;

    // Keep around original requested format for later validation
    int frameworkFormat = format;
    // Pick the right concrete pixel format given the endpoints as encoded in
    // the usage bits.  Every end-point pair needs explicit listing here.
    if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
        // Camera as producer
        if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE) {
            if (usage & GRALLOC_USAGE_HW_TEXTURE) {
                // Camera-to-display is RGBA
                format = HAL_PIXEL_FORMAT_RGBA_8888;
            } else if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) {
                // Camera-to-encoder is NV21
                format = HAL_PIXEL_FORMAT_YCrCb_420_SP;
            } else if ((usage & GRALLOC_USAGE_HW_CAMERA_MASK) ==
                    GRALLOC_USAGE_HW_CAMERA_ZSL) {
                // Camera-to-ZSL-queue is RGB_888
                format = HAL_PIXEL_FORMAT_RGB_888;
            }
        }

        if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
            ALOGE("gralloc_alloc: Requested auto format selection, "
                    "but no known format for this usage: %d x %d, usage %x",
                    w, h, usage);
            return -EINVAL;
        }
    } else if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
        // Flexible framework-accessible YUV format; map to NV21 for now
        if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE) {
            format = HAL_PIXEL_FORMAT_YCrCb_420_SP;
        }
        if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
            ALOGE("gralloc_alloc: Requested YCbCr_420_888, but no known "
                    "specific format for this usage: %d x %d, usage %x",
                    w, h, usage);
        }
    }
    bool yuv_format = false;

    int ashmem_size = 0;
    int stride = w;

    GLenum glFormat = 0;
    GLenum glType = 0;

    int bpp = 0;
    int align = 1;
    switch (format) {
        case HAL_PIXEL_FORMAT_RGBA_8888:
        case HAL_PIXEL_FORMAT_RGBX_8888:
        case HAL_PIXEL_FORMAT_BGRA_8888:
            bpp = 4;
            glFormat = GL_RGBA;
            glType = GL_UNSIGNED_BYTE;
            break;
        case HAL_PIXEL_FORMAT_RGB_888:
            bpp = 3;
            glFormat = GL_RGB;
            glType = GL_UNSIGNED_BYTE;
            break;
        case HAL_PIXEL_FORMAT_RGB_565:
            bpp = 2;
            glFormat = GL_RGB;
            glType = GL_UNSIGNED_SHORT_5_6_5;
            break;
        case HAL_PIXEL_FORMAT_RAW_SENSOR:
            bpp = 2;
            align = 16*bpp;
            if (! ((sw_read || hw_cam_read) && (sw_write || hw_cam_write) ) ) {
                // Raw sensor data only goes between camera and CPU
                return -EINVAL;
            }
            // Not expecting to actually create any GL surfaces for this
            glFormat = GL_LUMINANCE;
            glType = GL_UNSIGNED_SHORT;
            break;
        case HAL_PIXEL_FORMAT_BLOB:
            bpp = 1;
            if (! (sw_read && hw_cam_write) ) {
                // Blob data cannot be used by HW other than camera emulator
                return -EINVAL;
            }
            // Not expecting to actually create any GL surfaces for this
            glFormat = GL_LUMINANCE;
            glType = GL_UNSIGNED_BYTE;
            break;
        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
            align = 1;
            bpp = 1; // per-channel bpp
            yuv_format = true;
            // Not expecting to actually create any GL surfaces for this
            break;
        case HAL_PIXEL_FORMAT_YV12:
            align = 16;
            bpp = 1; // per-channel bpp
            yuv_format = true;
            // Not expecting to actually create any GL surfaces for this
            break;
        default:
            ALOGE("gralloc_alloc: Unknown format %d", format);
            return -EINVAL;
    }

    if (usage & GRALLOC_USAGE_HW_FB) {
        // keep space for postCounter
        ashmem_size += sizeof(uint32_t);
    }

    if (sw_read || sw_write || hw_cam_write || hw_vid_enc_read) {
        // keep space for image on guest memory if SW access is needed
        // or if the camera is doing writing
        if (yuv_format) {
            size_t yStride = (w*bpp + (align - 1)) & ~(align-1);
            size_t uvStride = (yStride / 2 + (align - 1)) & ~(align-1);
            size_t uvHeight = h / 2;
            ashmem_size += yStride * h + 2 * (uvHeight * uvStride);
            stride = yStride / bpp;
        } else {
            size_t bpr = (w*bpp + (align-1)) & ~(align-1);
            ashmem_size += (bpr * h);
            stride = bpr / bpp;
        }
    }

    D("gralloc_alloc format=%d, ashmem_size=%d, stride=%d, tid %d\n", format,
            ashmem_size, stride, gettid());

    //
    // Allocate space in ashmem if needed
    //
    int fd = -1;
    if (ashmem_size > 0) {
        // round to page size;
        ashmem_size = (ashmem_size + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1);

        fd = ashmem_create_region("gralloc-buffer", ashmem_size);
        if (fd < 0) {
            ALOGE("gralloc_alloc failed to create ashmem region: %s\n",
                    strerror(errno));
            return -errno;
        }
    }

    cb_handle_t *cb = new cb_handle_t(fd, ashmem_size, usage,
                                      w, h, frameworkFormat, format,
                                      glFormat, glType);

    if (ashmem_size > 0) {
        //
        // map ashmem region if exist
        //
        void *vaddr;
        int err = map_buffer(cb, &vaddr);
        if (err) {
            close(fd);
            delete cb;
            return err;
        }

        cb->setFd(fd);
    }

    //
    // Allocate ColorBuffer handle on the host (only if h/w access is allowed)
    // Only do this for some h/w usages, not all.
    //
    if (usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER |
                    GRALLOC_USAGE_HW_2D | GRALLOC_USAGE_HW_COMPOSER |
                    GRALLOC_USAGE_HW_FB) ) {
        DEFINE_HOST_CONNECTION;
        if (hostCon && rcEnc) {
            cb->hostHandle = rcEnc->rcCreateColorBuffer(rcEnc, w, h, glFormat);
            D("Created host ColorBuffer 0x%x\n", cb->hostHandle);
        }

        if (!cb->hostHandle) {
           // Could not create colorbuffer on host !!!
           close(fd);
           delete cb;
           return -EIO;
        }
    }

    //
    // alloc succeeded - insert the allocated handle to the allocated list
    //
    AllocListNode *node = new AllocListNode();
    pthread_mutex_lock(&grdev->lock);
    node->handle = cb;
    node->next =  grdev->allocListHead;
    node->prev =  NULL;
    if (grdev->allocListHead) {
        grdev->allocListHead->prev = node;
    }
    grdev->allocListHead = node;
    pthread_mutex_unlock(&grdev->lock);

    *pHandle = cb;
    if (frameworkFormat == HAL_PIXEL_FORMAT_YCbCr_420_888) {
        *pStride = 0;
    } else {
        *pStride = stride;
    }
    return 0;
}
예제 #27
0
bool dvmCompilerSetupCodeCache(void)
{
    int fd;

    /* Allocate the code cache */
    fd = ashmem_create_region("dalvik-jit-code-cache", gDvmJit.codeCacheSize);
    if (fd < 0) {
        ALOGE("Could not create %u-byte ashmem region for the JIT code cache",
             gDvmJit.codeCacheSize);
        return false;
    }
    gDvmJit.codeCache = mmap(NULL, gDvmJit.codeCacheSize,
                             PROT_READ | PROT_WRITE | PROT_EXEC,
                             MAP_PRIVATE , fd, 0);
    close(fd);
    if (gDvmJit.codeCache == MAP_FAILED) {
        ALOGE("Failed to mmap the JIT code cache of size %d: %s", gDvmJit.codeCacheSize, strerror(errno));
        return false;
    }

    gDvmJit.pageSizeMask = getpagesize() - 1;

    /* This can be found through "dalvik-jit-code-cache" in /proc/<pid>/maps */
    // ALOGD("Code cache starts at %p", gDvmJit.codeCache);

#ifndef ARCH_IA32
    /* Copy the template code into the beginning of the code cache */
    int templateSize = (intptr_t) dvmCompilerTemplateEnd -
                       (intptr_t) dvmCompilerTemplateStart;
    memcpy((void *) gDvmJit.codeCache,
           (void *) dvmCompilerTemplateStart,
           templateSize);

    /*
     * Work around a CPU bug by keeping the 32-bit ARM handler code in its own
     * page.
     */
    if (dvmCompilerInstructionSet() == DALVIK_JIT_THUMB2) {
        templateSize = (templateSize + 4095) & ~4095;
    }

    gDvmJit.templateSize = templateSize;
    gDvmJit.codeCacheByteUsed = templateSize;

    /* Only flush the part in the code cache that is being used now */
    dvmCompilerCacheFlush((intptr_t) gDvmJit.codeCache,
                          (intptr_t) gDvmJit.codeCache + templateSize);
#else
    gDvmJit.codeCacheByteUsed = 0;
    stream = (char*)gDvmJit.codeCache + gDvmJit.codeCacheByteUsed;
    ALOGV("codeCache = %p stream = %p before initJIT", gDvmJit.codeCache, stream);
    streamStart = stream;
    initJIT(NULL, NULL);
    gDvmJit.templateSize = (stream - streamStart);
    gDvmJit.codeCacheByteUsed = (stream - streamStart);
    ALOGV("stream = %p after initJIT", stream);
#endif

    int result = mprotect(gDvmJit.codeCache, gDvmJit.codeCacheSize,
                          PROTECT_CODE_CACHE_ATTRS);

    if (result == -1) {
        ALOGE("Failed to remove the write permission for the code cache");
        dvmAbort();
    }

    return true;
}
status_t InputChannel::openInputChannelPair(const String8& name,
        sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel) {
    status_t result;

    String8 ashmemName("InputChannel ");
    ashmemName.append(name);
    int serverAshmemFd = ashmem_create_region(ashmemName.string(), DEFAULT_MESSAGE_BUFFER_SIZE);
    if (serverAshmemFd < 0) {
        result = -errno;
        ALOGE("channel '%s' ~ Could not create shared memory region. errno=%d",
                name.string(), errno);
    } else {
        result = ashmem_set_prot_region(serverAshmemFd, PROT_READ | PROT_WRITE);
        if (result < 0) {
            ALOGE("channel '%s' ~ Error %d trying to set protection of ashmem fd %d.",
                    name.string(), result, serverAshmemFd);
        } else {
            // Dup the file descriptor because the server and client input channel objects that
            // are returned may have different lifetimes but they share the same shared memory region.
            int clientAshmemFd;
            clientAshmemFd = dup(serverAshmemFd);
            if (clientAshmemFd < 0) {
                result = -errno;
                ALOGE("channel '%s' ~ Could not dup() shared memory region fd. errno=%d",
                        name.string(), errno);
            } else {
                int forward[2];
                if (pipe(forward)) {
                    result = -errno;
                    ALOGE("channel '%s' ~ Could not create forward pipe.  errno=%d",
                            name.string(), errno);
                } else {
                    int reverse[2];
                    if (pipe(reverse)) {
                        result = -errno;
                        ALOGE("channel '%s' ~ Could not create reverse pipe.  errno=%d",
                                name.string(), errno);
                    } else {
                        String8 serverChannelName = name;
                        serverChannelName.append(" (server)");
                        outServerChannel = new InputChannel(serverChannelName,
                                serverAshmemFd, reverse[0], forward[1]);

                        String8 clientChannelName = name;
                        clientChannelName.append(" (client)");
                        outClientChannel = new InputChannel(clientChannelName,
                                clientAshmemFd, forward[0], reverse[1]);
                        return OK;
                    }
                    ::close(forward[0]);
                    ::close(forward[1]);
                }
                ::close(clientAshmemFd);
            }
        }
        ::close(serverAshmemFd);
    }

    outServerChannel.clear();
    outClientChannel.clear();
    return result;
}
//
// gralloc device functions (alloc interface)
//
static int gralloc_alloc(alloc_device_t* dev,
                         int w, int h, int format, int usage,
                         buffer_handle_t* pHandle, int* pStride)
{
    LOGD("gralloc_alloc w=%d h=%d usage=0x%x\n", w, h, usage);

    gralloc_device_t *grdev = (gralloc_device_t *)dev;
    if (!grdev || !pHandle || !pStride)
        return -EINVAL;

    //
    // Validate usage: buffer cannot be written both by s/w and h/w access.
    //
    bool sw_write = (0 != (usage & GRALLOC_USAGE_SW_WRITE_MASK));
    bool hw_write = (usage & GRALLOC_USAGE_HW_RENDER);
    if (hw_write && sw_write) {
        return -EINVAL;
    }

    int ashmem_size = 0;
    *pStride = 0;
    GLenum glFormat = 0;

    int bpp = 0;
    switch (format) {
        case HAL_PIXEL_FORMAT_RGBA_8888:
        case HAL_PIXEL_FORMAT_RGBX_8888:
        case HAL_PIXEL_FORMAT_BGRA_8888:
            bpp = 4;
            glFormat = GL_RGBA;
            break;
        case HAL_PIXEL_FORMAT_RGB_888:
            bpp = 3;
            glFormat = GL_RGB;
            break;
        case HAL_PIXEL_FORMAT_RGB_565:
            bpp = 2;
            glFormat = GL_RGB565_OES;
            break;
        case HAL_PIXEL_FORMAT_RGBA_5551:
            bpp = 2;
            glFormat = GL_RGB5_A1_OES;
            break;
        case HAL_PIXEL_FORMAT_RGBA_4444:
            bpp = 2;
            glFormat = GL_RGBA4_OES;
            break;

        default:
            return -EINVAL;
    }

    if (usage & GRALLOC_USAGE_HW_FB) {
        // keep space for postCounter
        ashmem_size += sizeof(uint32_t);
    }

    if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) {
        // keep space for image on guest memory if SW access is needed
        int align = 1;
        size_t bpr = (w*bpp + (align-1)) & ~(align-1);
        ashmem_size += (bpr * h);
        *pStride = bpr / bpp;
    }

    LOGD("gralloc_alloc ashmem_size=%d\n", ashmem_size);

    //
    // Allocate space in ashmem if needed
    //
    int fd = -1;
    if (ashmem_size > 0) {
        // round to page size;
        ashmem_size = (ashmem_size + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1);

        fd = ashmem_create_region("gralloc-buffer", ashmem_size);
        if (fd < 0) {
            LOGE("gralloc_alloc failed to create ashmem region err=%d\n", errno);
            return -errno;
        }
    }

    cb_handle_t *cb = new cb_handle_t(fd, ashmem_size, usage, w, h, glFormat);

    if (ashmem_size > 0) {
        //
        // map ashmem region if exist
        //
        void *vaddr;
        int err = map_buffer(cb, &vaddr);
        if (err) {
            close(fd);
            delete cb;
            return err;
        }
    }

    //
    // Allocate ColorBuffer handle on the host (only if h/w access is allowed)
    //
    if (usage & GRALLOC_USAGE_HW_MASK) {
        DEFINE_HOST_CONNECTION;
        if (hostCon && rcEnc) {
            cb->hostHandle = rcEnc->rcCreateColorBuffer(rcEnc, w, h, glFormat);
            LOGD("Created host ColorBuffer 0x%x\n", cb->hostHandle);
        }

        if (!cb->hostHandle) {
           // Could not create colorbuffer on host !!!
           close(fd);
           delete cb;
           return -EIO;
        }
    }

    //
    // alloc succeeded - insert the allocated handle to the allocated list
    //
    AllocListNode *node = new AllocListNode();
    pthread_mutex_lock(&grdev->lock);
    node->handle = cb;
    node->next =  grdev->allocListHead;
    node->prev =  NULL;
    if (grdev->allocListHead) {
        grdev->allocListHead->prev = node;
    }
    grdev->allocListHead = node;
    pthread_mutex_unlock(&grdev->lock);

    *pHandle = cb;
    return 0;
}
예제 #30
0
int main(int argc, const char *argv[])
{
	int i;
	int count = 0;
	int fd;
	int ret;

	/* Open a file for writing.
  *  - Creating the file if it doesn't exist.
  *  - Truncating it to 0 size if it already exists. (not really needed)
  *
  * Note: "O_WRONLY" mode is not sufficient when mmaping.
  */
loop:
	fd = ashmem_create_region("zzytest", LEN);
	if (fd < 0)
	{
	    perror("Error opening file for writing");
	    exit(EXIT_FAILURE);
	}

	char ash_name[ASHMEM_NAME_LEN] = {0};
	ret = ioctl(fd, ASHMEM_GET_NAME, ash_name);
	if(ret >= 0) {
		printf("ash_name=%s\n", ash_name);	
	}

	// Now the file is ready to be mmapped.
	char *map = mmap(0, LEN, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
	if (map == MAP_FAILED)
	{
	    close(fd);
	    perror("Error mmapping the file");
	    exit(EXIT_FAILURE);
	}
	
	char s[256], name[256];
	memset(s, 0, 256);
	memset(name, 0, 256);
	snprintf(s, 255, "/proc/%d/fd/%d", getpid(), fd);
	readlink(s, name, 255);
	printf("Succeeded to mmap program binaries. File descriptor is %d, and path is %s\n", fd, name);

	printf("memset data\n");
	memset(map, '1', LEN-1);
	//printf("%c\n", map[count%textsize]);
	
	// Write it now to disk
	if (msync(map, LEN, MS_SYNC) == -1)
	{
	    perror("Could not sync the file to disk");
	}
	sleep(1);
	printf("count=%d\n", count++);
	printf("fd=%d\n", fd);
	printf("map=%x\n", map);
	
	// close fd
	close(fd);
	
	// Don't forget to free the mmapped memory
	#if 1
	if (munmap(map, LEN) == -1)
	{
	    close(fd);
	    perror("Error un-mmapping the file");
	    exit(EXIT_FAILURE);
	}
	#endif
goto loop;

	return 0;
}