Merge "Fix SharedBuffer. Remove aref."
This commit is contained in:
commit
069517574e
|
@ -1,58 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2013 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _CUTILS_AREF_H_
|
|
||||||
#define _CUTILS_AREF_H_
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <sys/cdefs.h>
|
|
||||||
|
|
||||||
#include <cutils/atomic.h>
|
|
||||||
|
|
||||||
__BEGIN_DECLS
|
|
||||||
|
|
||||||
#define AREF_TO_ITEM(aref, container, member) \
|
|
||||||
(container *) (((char*) (aref)) - offsetof(container, member))
|
|
||||||
|
|
||||||
struct aref
|
|
||||||
{
|
|
||||||
volatile int32_t count;
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline void aref_init(struct aref *r)
|
|
||||||
{
|
|
||||||
r->count = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int32_t aref_count(struct aref *r)
|
|
||||||
{
|
|
||||||
return r->count;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void aref_get(struct aref *r)
|
|
||||||
{
|
|
||||||
android_atomic_inc(&r->count);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void aref_put(struct aref *r, void (*release)(struct aref *))
|
|
||||||
{
|
|
||||||
if (android_atomic_dec(&r->count) == 1)
|
|
||||||
release(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
__END_DECLS
|
|
||||||
|
|
||||||
#endif // _CUTILS_AREF_H_
|
|
|
@ -20,7 +20,6 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <log/log.h>
|
#include <log/log.h>
|
||||||
#include <utils/Atomic.h>
|
|
||||||
|
|
||||||
#include "SharedBuffer.h"
|
#include "SharedBuffer.h"
|
||||||
|
|
||||||
|
@ -37,18 +36,19 @@ SharedBuffer* SharedBuffer::alloc(size_t size)
|
||||||
|
|
||||||
SharedBuffer* sb = static_cast<SharedBuffer *>(malloc(sizeof(SharedBuffer) + size));
|
SharedBuffer* sb = static_cast<SharedBuffer *>(malloc(sizeof(SharedBuffer) + size));
|
||||||
if (sb) {
|
if (sb) {
|
||||||
sb->mRefs = 1;
|
// Should be std::atomic_init(&sb->mRefs, 1);
|
||||||
|
// But that generates a warning with some compilers.
|
||||||
|
// The following is OK on Android-supported platforms.
|
||||||
|
sb->mRefs.store(1, std::memory_order_relaxed);
|
||||||
sb->mSize = size;
|
sb->mSize = size;
|
||||||
}
|
}
|
||||||
return sb;
|
return sb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ssize_t SharedBuffer::dealloc(const SharedBuffer* released)
|
void SharedBuffer::dealloc(const SharedBuffer* released)
|
||||||
{
|
{
|
||||||
if (released->mRefs != 0) return -1; // XXX: invalid operation
|
|
||||||
free(const_cast<SharedBuffer*>(released));
|
free(const_cast<SharedBuffer*>(released));
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedBuffer* SharedBuffer::edit() const
|
SharedBuffer* SharedBuffer::edit() const
|
||||||
|
@ -108,14 +108,15 @@ SharedBuffer* SharedBuffer::reset(size_t new_size) const
|
||||||
}
|
}
|
||||||
|
|
||||||
void SharedBuffer::acquire() const {
|
void SharedBuffer::acquire() const {
|
||||||
android_atomic_inc(&mRefs);
|
mRefs.fetch_add(1, std::memory_order_relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t SharedBuffer::release(uint32_t flags) const
|
int32_t SharedBuffer::release(uint32_t flags) const
|
||||||
{
|
{
|
||||||
int32_t prev = 1;
|
int32_t prev = 1;
|
||||||
if (onlyOwner() || ((prev = android_atomic_dec(&mRefs)) == 1)) {
|
if (onlyOwner() || ((prev = mRefs.fetch_sub(1, std::memory_order_release) == 1)
|
||||||
mRefs = 0;
|
&& (atomic_thread_fence(std::memory_order_acquire), true))) {
|
||||||
|
mRefs.store(0, std::memory_order_relaxed);
|
||||||
if ((flags & eKeepStorage) == 0) {
|
if ((flags & eKeepStorage) == 0) {
|
||||||
free(const_cast<SharedBuffer*>(this));
|
free(const_cast<SharedBuffer*>(this));
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,9 +14,14 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DEPRECATED. DO NOT USE FOR NEW CODE.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef ANDROID_SHARED_BUFFER_H
|
#ifndef ANDROID_SHARED_BUFFER_H
|
||||||
#define ANDROID_SHARED_BUFFER_H
|
#define ANDROID_SHARED_BUFFER_H
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
@ -43,7 +48,7 @@ public:
|
||||||
* In other words, the buffer must have been release by all its
|
* In other words, the buffer must have been release by all its
|
||||||
* users.
|
* users.
|
||||||
*/
|
*/
|
||||||
static ssize_t dealloc(const SharedBuffer* released);
|
static void dealloc(const SharedBuffer* released);
|
||||||
|
|
||||||
//! access the data for read
|
//! access the data for read
|
||||||
inline const void* data() const;
|
inline const void* data() const;
|
||||||
|
@ -94,12 +99,16 @@ private:
|
||||||
SharedBuffer(const SharedBuffer&);
|
SharedBuffer(const SharedBuffer&);
|
||||||
SharedBuffer& operator = (const SharedBuffer&);
|
SharedBuffer& operator = (const SharedBuffer&);
|
||||||
|
|
||||||
// 16 bytes. must be sized to preserve correct alignment.
|
// Must be sized to preserve correct alignment.
|
||||||
mutable int32_t mRefs;
|
mutable std::atomic<int32_t> mRefs;
|
||||||
size_t mSize;
|
size_t mSize;
|
||||||
uint32_t mReserved[2];
|
uint32_t mReserved[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static_assert(sizeof(SharedBuffer) % 8 == 0
|
||||||
|
&& (sizeof(size_t) > 4 || sizeof(SharedBuffer) == 16),
|
||||||
|
"SharedBuffer has unexpected size");
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
const void* SharedBuffer::data() const {
|
const void* SharedBuffer::data() const {
|
||||||
|
@ -127,7 +136,7 @@ size_t SharedBuffer::sizeFromData(const void* data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SharedBuffer::onlyOwner() const {
|
bool SharedBuffer::onlyOwner() const {
|
||||||
return (mRefs == 1);
|
return (mRefs.load(std::memory_order_acquire) == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
}; // namespace android
|
}; // namespace android
|
||||||
|
|
Loading…
Reference in New Issue