/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include <unistd.h>
#include <sys/mman.h>
#include "SkDiscardableMemory.h"
#include "SkDiscardableMemoryPool.h"
#include "SkTypes.h"
#include "android/ashmem.h"

////////////////////////////////////////////////////////////////////////////////
namespace {
/**
 *  DiscardableMemory implementation that uses the Android kernel's
 *  ashmem (Android shared memory).
 */
class SkAshmemDiscardableMemory : public SkDiscardableMemory {
public:
    SkAshmemDiscardableMemory(int fd, void* address, size_t size);
    virtual ~SkAshmemDiscardableMemory();
    virtual bool lock() SK_OVERRIDE;
    virtual void* data() SK_OVERRIDE;
    virtual void unlock() SK_OVERRIDE;
    static SkAshmemDiscardableMemory* Create(size_t bytes);

private:
    bool         fLocked;
    int          fFd;
    void*        fMemory;
    const size_t fSize;
};

SkAshmemDiscardableMemory::SkAshmemDiscardableMemory(int fd,
                                                     void* address,
                                                     size_t size)
    : fLocked(true)  // Ashmem pages are pinned by default.
    , fFd(fd)
    , fMemory(address)
    , fSize(size) {
    SkASSERT(fFd >= 0);
    SkASSERT(fMemory != NULL);
    SkASSERT(fSize > 0);
}

SkAshmemDiscardableMemory::~SkAshmemDiscardableMemory() {
    SkASSERT(!fLocked);
    if (NULL != fMemory) {
        munmap(fMemory, fSize);
    }
    if (fFd != -1) {
        close(fFd);
    }
}

bool SkAshmemDiscardableMemory::lock() {
    SkASSERT(!fLocked);
    if (-1 == fFd) {
        fLocked = false;
        return false;
    }
    SkASSERT(fMemory != NULL);
    if (fLocked || (ASHMEM_NOT_PURGED == ashmem_pin_region(fFd, 0, 0))) {
        fLocked = true;
        return true;
    } else {
        munmap(fMemory, fSize);
        fMemory = NULL;

        close(fFd);
        fFd = -1;
        fLocked = false;
        return false;
    }
}

void* SkAshmemDiscardableMemory::data() {
    SkASSERT(fLocked);
    return fLocked ? fMemory : NULL;
}

void SkAshmemDiscardableMemory::unlock() {
    SkASSERT(fLocked);
    if (fLocked && (fFd != -1)) {
        ashmem_unpin_region(fFd, 0, 0);
    }
    fLocked = false;
}

SkAshmemDiscardableMemory* SkAshmemDiscardableMemory::Create(size_t bytes) {
    // ashmem likes lengths on page boundaries.
    const size_t mask = getpagesize() - 1;
    size_t size = (bytes + mask) & ~mask;

    static const char name[] = "Skia_Ashmem_Discardable_Memory";
    int fd = ashmem_create_region(name, size);
    if (fd < 0) {
        return NULL;
    }
    if (0 != ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE)) {
        close(fd);
        return NULL;
    }
    void* addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
    if ((MAP_FAILED == addr) || (NULL == addr)) {
        close(fd);
        return NULL;
    }

    return SkNEW_ARGS(SkAshmemDiscardableMemory, (fd, addr, size));
}
}  // namespace
////////////////////////////////////////////////////////////////////////////////

#ifndef SK_ASHMEM_MINIMUM_MEMORY_SIZE
// number taken from android/graphics/BitmapFactory.cpp
#define SK_ASHMEM_MINIMUM_MEMORY_SIZE (32 * 1024)
#endif  // SK_ASHMEM_MINIMUM_MEMORY_SIZE
SkDiscardableMemory* SkDiscardableMemory::Create(size_t bytes) {
    if (bytes < SK_ASHMEM_MINIMUM_MEMORY_SIZE) {
        return SkGetGlobalDiscardableMemoryPool()->create(bytes);
    } else {
        return SkAshmemDiscardableMemory::Create(bytes);
    }
}
