summaryrefslogtreecommitdiffstats
path: root/modules/gralloc/mapper.cpp
diff options
context:
space:
mode:
authorMathias Agopian <mathias@google.com>2009-05-05 20:21:57 -0700
committerMathias Agopian <mathias@google.com>2009-05-05 20:49:49 -0700
commit485e69809aef8bf301b6bf19c03dc2d7693aaa1a (patch)
tree58775a86be0138fca964c5ec9858b1177d4da3d9 /modules/gralloc/mapper.cpp
parent295190f426a209cf08a21476f15e0e281db6fcb5 (diff)
downloadhardware_libhardware-485e69809aef8bf301b6bf19c03dc2d7693aaa1a.zip
hardware_libhardware-485e69809aef8bf301b6bf19c03dc2d7693aaa1a.tar.gz
hardware_libhardware-485e69809aef8bf301b6bf19c03dc2d7693aaa1a.tar.bz2
better documentation and implementation for lock/unlock
Diffstat (limited to 'modules/gralloc/mapper.cpp')
-rw-r--r--modules/gralloc/mapper.cpp94
1 files changed, 69 insertions, 25 deletions
diff --git a/modules/gralloc/mapper.cpp b/modules/gralloc/mapper.cpp
index 94be43b..bbcffac 100644
--- a/modules/gralloc/mapper.cpp
+++ b/modules/gralloc/mapper.cpp
@@ -220,8 +220,9 @@ int gralloc_register_buffer(gralloc_module_t const* module,
*/
private_handle_t* hnd = (private_handle_t*)(handle);
hnd->base = 0;
- hnd->flags &= ~(private_handle_t::PRIV_FLAGS_LOCKED |
- private_handle_t::PRIV_FLAGS_MAPPED);
+ hnd->flags &= ~private_handle_t::PRIV_FLAGS_MAPPED;
+ hnd->lockState = 0;
+ hnd->writeOwner = 0;
return 0;
}
@@ -240,8 +241,8 @@ int gralloc_unregister_buffer(gralloc_module_t const* module,
private_handle_t* hnd = (private_handle_t*)(handle);
- LOGE_IF(hnd->flags & private_handle_t::PRIV_FLAGS_LOCKED,
- "handle %p still locked", hnd);
+ LOGE_IF(hnd->lockState, "handle %p still locked (state=%08x)",
+ hnd, hnd->lockState);
if (hnd->flags & private_handle_t::PRIV_FLAGS_MAPPED) {
if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
@@ -260,23 +261,51 @@ int gralloc_lock(gralloc_module_t const* module,
int l, int t, int w, int h,
void** vaddr)
{
- // FIXME: gralloc_lock() needs implementation
-
if (private_handle_t::validate(handle) < 0)
return -EINVAL;
int err = 0;
private_handle_t* hnd = (private_handle_t*)(handle);
+ int32_t current_value, new_value;
+ int retry;
+
+ do {
+ current_value = hnd->lockState;
+ new_value = current_value;
+
+ if (current_value>>31) {
+ // already locked for write
+ LOGE("handle %p already locked for write", handle);
+ return -EBUSY;
+ } else if (current_value<<1) {
+ // already locked for read
+ if (usage & (GRALLOC_USAGE_SW_WRITE_MASK | GRALLOC_USAGE_HW_RENDER)) {
+ LOGE("handle %p already locked for read", handle);
+ return -EBUSY;
+ } else {
+ // this is not an error, but for now we want to know
+ LOGD("%p already locked for read... count = %d",
+ handle, (current_value & ~(1<<31)));
+ }
+ }
- // already locked
- if (hnd->flags & private_handle_t::PRIV_FLAGS_LOCKED) {
- LOGE("handle %p already locked", handle);
- return -EBUSY;
- }
+ // not currently locked
+ if (usage & (GRALLOC_USAGE_SW_WRITE_MASK | GRALLOC_USAGE_HW_RENDER)) {
+ // locking for write
+ new_value |= (1<<31);
+ }
+ new_value++;
+
+ retry = android_atomic_cmpxchg(current_value, new_value,
+ (volatile int32_t*)&hnd->lockState);
+ } while (retry);
- uint32_t mask = GRALLOC_USAGE_SW_READ_MASK |
- GRALLOC_USAGE_SW_WRITE_MASK;
- if ((usage & mask) && vaddr){
+ if (new_value>>31) {
+ // locking for write, store the tid
+ hnd->writeOwner = gettid();
+ }
+
+ if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) {
if (hnd->flags & private_handle_t::PRIV_FLAGS_MAPPED) {
*vaddr = (void*)hnd->base;
} else {
@@ -284,25 +313,41 @@ int gralloc_lock(gralloc_module_t const* module,
err = gralloc_map(module, handle, vaddr);
}
}
-
- hnd->flags |= private_handle_t::PRIV_FLAGS_LOCKED;
+
return err;
}
int gralloc_unlock(gralloc_module_t const* module,
buffer_handle_t handle)
{
- // FIXME: gralloc_unlock() needs implementation
if (private_handle_t::validate(handle) < 0)
return -EINVAL;
private_handle_t* hnd = (private_handle_t*)(handle);
+ int32_t current_value, new_value;
+
+ do {
+ current_value = hnd->lockState;
+ new_value = current_value;
+
+ if (current_value>>31) {
+ // locked for write
+ if (hnd->writeOwner == gettid()) {
+ hnd->writeOwner = 0;
+ new_value &= ~(1<<31);
+ }
+ }
+
+ if ((new_value<<1) == 0) {
+ LOGE("handle %p not locked", handle);
+ return -EINVAL;
+ }
+
+ new_value--;
+
+ } while (android_atomic_cmpxchg(current_value, new_value,
+ (volatile int32_t*)&hnd->lockState));
- // not locked
- if (!(hnd->flags & private_handle_t::PRIV_FLAGS_LOCKED)) {
- LOGE("handle %p is not locked", handle);
- return -EINVAL;
- }
/* FOR DEBUGGING
if (hnd->flags & private_handle_t::PRIV_FLAGS_MAPPED) {
@@ -310,8 +355,7 @@ int gralloc_unlock(gralloc_module_t const* module,
hnd->flags &= ~private_handle_t::PRIV_FLAGS_MAPPED;
}
}
- */
-
- hnd->flags &= ~private_handle_t::PRIV_FLAGS_LOCKED;
+ */
+
return 0;
}