diff options
author | Mathias Agopian <mathias@google.com> | 2009-05-05 20:21:57 -0700 |
---|---|---|
committer | Mathias Agopian <mathias@google.com> | 2009-05-05 20:49:49 -0700 |
commit | 485e69809aef8bf301b6bf19c03dc2d7693aaa1a (patch) | |
tree | 58775a86be0138fca964c5ec9858b1177d4da3d9 /modules/gralloc/mapper.cpp | |
parent | 295190f426a209cf08a21476f15e0e281db6fcb5 (diff) | |
download | hardware_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.cpp | 94 |
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; } |