mirror of https://github.com/ARMmbed/mbed-os.git
Add init reference count to all block devices
parent
57bd7109f8
commit
a709e91920
|
@ -92,10 +92,6 @@ void test_slicing() {
|
||||||
TEST_ASSERT_EQUAL(0xff & rand(), read_block[i]);
|
TEST_ASSERT_EQUAL(0xff & rand(), read_block[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
err = slice1.deinit();
|
|
||||||
TEST_ASSERT_EQUAL(0, err);
|
|
||||||
|
|
||||||
|
|
||||||
// Test with second slice of block device
|
// Test with second slice of block device
|
||||||
err = slice2.init();
|
err = slice2.init();
|
||||||
TEST_ASSERT_EQUAL(0, err);
|
TEST_ASSERT_EQUAL(0, err);
|
||||||
|
@ -109,6 +105,10 @@ void test_slicing() {
|
||||||
write_block[i] = 0xff & rand();
|
write_block[i] = 0xff & rand();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deinitialize slice1 here, to check whether init reference count works
|
||||||
|
err = slice1.deinit();
|
||||||
|
TEST_ASSERT_EQUAL(0, err);
|
||||||
|
|
||||||
// Write, sync, and read the block
|
// Write, sync, and read the block
|
||||||
err = slice2.program(write_block, 0, BLOCK_SIZE);
|
err = slice2.program(write_block, 0, BLOCK_SIZE);
|
||||||
TEST_ASSERT_EQUAL(0, err);
|
TEST_ASSERT_EQUAL(0, err);
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#include "BufferedBlockDevice.h"
|
#include "BufferedBlockDevice.h"
|
||||||
#include "mbed_assert.h"
|
#include "mbed_assert.h"
|
||||||
|
#include "mbed_critical.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
@ -25,7 +26,7 @@ static inline uint32_t align_down(bd_size_t val, bd_size_t size)
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferedBlockDevice::BufferedBlockDevice(BlockDevice *bd)
|
BufferedBlockDevice::BufferedBlockDevice(BlockDevice *bd)
|
||||||
: _bd(bd), _bd_program_size(0), _curr_aligned_addr(0), _flushed(true), _cache(0)
|
: _bd(bd), _bd_program_size(0), _curr_aligned_addr(0), _flushed(true), _cache(0), _init_ref_count(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +37,12 @@ BufferedBlockDevice::~BufferedBlockDevice()
|
||||||
|
|
||||||
int BufferedBlockDevice::init()
|
int BufferedBlockDevice::init()
|
||||||
{
|
{
|
||||||
|
uint32_t val = core_util_atomic_incr_u32(&_init_ref_count, 1);
|
||||||
|
|
||||||
|
if (val != 1) {
|
||||||
|
return BD_ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
int err = _bd->init();
|
int err = _bd->init();
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
|
@ -55,6 +62,12 @@ int BufferedBlockDevice::init()
|
||||||
|
|
||||||
int BufferedBlockDevice::deinit()
|
int BufferedBlockDevice::deinit()
|
||||||
{
|
{
|
||||||
|
uint32_t val = core_util_atomic_decr_u32(&_init_ref_count, 1);
|
||||||
|
|
||||||
|
if (val) {
|
||||||
|
return BD_ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
delete[] _cache;
|
delete[] _cache;
|
||||||
_cache = 0;
|
_cache = 0;
|
||||||
return _bd->deinit();
|
return _bd->deinit();
|
||||||
|
|
|
@ -153,6 +153,7 @@ protected:
|
||||||
bd_size_t _curr_aligned_addr;
|
bd_size_t _curr_aligned_addr;
|
||||||
bool _flushed;
|
bool _flushed;
|
||||||
uint8_t *_cache;
|
uint8_t *_cache;
|
||||||
|
uint32_t _init_ref_count;
|
||||||
|
|
||||||
/** Flush data in cache
|
/** Flush data in cache
|
||||||
*
|
*
|
||||||
|
|
|
@ -15,12 +15,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ChainingBlockDevice.h"
|
#include "ChainingBlockDevice.h"
|
||||||
|
#include "mbed_critical.h"
|
||||||
|
|
||||||
|
|
||||||
ChainingBlockDevice::ChainingBlockDevice(BlockDevice **bds, size_t bd_count)
|
ChainingBlockDevice::ChainingBlockDevice(BlockDevice **bds, size_t bd_count)
|
||||||
: _bds(bds), _bd_count(bd_count)
|
: _bds(bds), _bd_count(bd_count)
|
||||||
, _read_size(0), _program_size(0), _erase_size(0), _size(0)
|
, _read_size(0), _program_size(0), _erase_size(0), _size(0)
|
||||||
, _erase_value(-1)
|
, _erase_value(-1), _init_ref_count(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +32,12 @@ static bool is_aligned(uint64_t x, uint64_t alignment)
|
||||||
|
|
||||||
int ChainingBlockDevice::init()
|
int ChainingBlockDevice::init()
|
||||||
{
|
{
|
||||||
|
uint32_t val = core_util_atomic_incr_u32(&_init_ref_count, 1);
|
||||||
|
|
||||||
|
if (val != 1) {
|
||||||
|
return BD_ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
_read_size = 0;
|
_read_size = 0;
|
||||||
_program_size = 0;
|
_program_size = 0;
|
||||||
_erase_size = 0;
|
_erase_size = 0;
|
||||||
|
@ -83,6 +90,12 @@ int ChainingBlockDevice::init()
|
||||||
|
|
||||||
int ChainingBlockDevice::deinit()
|
int ChainingBlockDevice::deinit()
|
||||||
{
|
{
|
||||||
|
uint32_t val = core_util_atomic_decr_u32(&_init_ref_count, 1);
|
||||||
|
|
||||||
|
if (val) {
|
||||||
|
return BD_ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < _bd_count; i++) {
|
for (size_t i = 0; i < _bd_count; i++) {
|
||||||
int err = _bds[i]->deinit();
|
int err = _bds[i]->deinit();
|
||||||
if (err) {
|
if (err) {
|
||||||
|
|
|
@ -64,7 +64,7 @@ public:
|
||||||
template <size_t Size>
|
template <size_t Size>
|
||||||
ChainingBlockDevice(BlockDevice *(&bds)[Size])
|
ChainingBlockDevice(BlockDevice *(&bds)[Size])
|
||||||
: _bds(bds), _bd_count(sizeof(bds) / sizeof(bds[0]))
|
: _bds(bds), _bd_count(sizeof(bds) / sizeof(bds[0]))
|
||||||
, _read_size(0), _program_size(0), _erase_size(0), _size(0)
|
, _read_size(0), _program_size(0), _erase_size(0), _size(0), _init_ref_count(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,6 +175,7 @@ protected:
|
||||||
bd_size_t _erase_size;
|
bd_size_t _erase_size;
|
||||||
bd_size_t _size;
|
bd_size_t _size;
|
||||||
int _erase_value;
|
int _erase_value;
|
||||||
|
uint32_t _init_ref_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -16,10 +16,11 @@
|
||||||
|
|
||||||
#include "ExhaustibleBlockDevice.h"
|
#include "ExhaustibleBlockDevice.h"
|
||||||
#include "mbed.h"
|
#include "mbed.h"
|
||||||
|
#include "mbed_critical.h"
|
||||||
|
|
||||||
|
|
||||||
ExhaustibleBlockDevice::ExhaustibleBlockDevice(BlockDevice *bd, uint32_t erase_cycles)
|
ExhaustibleBlockDevice::ExhaustibleBlockDevice(BlockDevice *bd, uint32_t erase_cycles)
|
||||||
: _bd(bd), _erase_array(NULL), _erase_cycles(erase_cycles)
|
: _bd(bd), _erase_array(NULL), _erase_cycles(erase_cycles), _init_ref_count(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,6 +31,12 @@ ExhaustibleBlockDevice::~ExhaustibleBlockDevice()
|
||||||
|
|
||||||
int ExhaustibleBlockDevice::init()
|
int ExhaustibleBlockDevice::init()
|
||||||
{
|
{
|
||||||
|
uint32_t val = core_util_atomic_incr_u32(&_init_ref_count, 1);
|
||||||
|
|
||||||
|
if (val != 1) {
|
||||||
|
return BD_ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
int err = _bd->init();
|
int err = _bd->init();
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
|
@ -48,6 +55,12 @@ int ExhaustibleBlockDevice::init()
|
||||||
|
|
||||||
int ExhaustibleBlockDevice::deinit()
|
int ExhaustibleBlockDevice::deinit()
|
||||||
{
|
{
|
||||||
|
core_util_atomic_decr_u32(&_init_ref_count, 1);
|
||||||
|
|
||||||
|
if (_init_ref_count) {
|
||||||
|
return BD_ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
// _erase_array is lazily cleaned up in destructor to allow
|
// _erase_array is lazily cleaned up in destructor to allow
|
||||||
// data to live across de/reinitialization
|
// data to live across de/reinitialization
|
||||||
return _bd->deinit();
|
return _bd->deinit();
|
||||||
|
|
|
@ -154,6 +154,7 @@ private:
|
||||||
BlockDevice *_bd;
|
BlockDevice *_bd;
|
||||||
uint32_t *_erase_array;
|
uint32_t *_erase_array;
|
||||||
uint32_t _erase_cycles;
|
uint32_t _erase_cycles;
|
||||||
|
uint32_t _init_ref_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#include "FlashSimBlockDevice.h"
|
#include "FlashSimBlockDevice.h"
|
||||||
#include "mbed_assert.h"
|
#include "mbed_assert.h"
|
||||||
|
#include "mbed_critical.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -29,7 +30,7 @@ static inline uint32_t align_up(bd_size_t val, bd_size_t size)
|
||||||
|
|
||||||
FlashSimBlockDevice::FlashSimBlockDevice(BlockDevice *bd, uint8_t erase_value) :
|
FlashSimBlockDevice::FlashSimBlockDevice(BlockDevice *bd, uint8_t erase_value) :
|
||||||
_erase_value(erase_value), _blank_buf_size(0),
|
_erase_value(erase_value), _blank_buf_size(0),
|
||||||
_blank_buf(0), _bd(bd)
|
_blank_buf(0), _bd(bd), _init_ref_count(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +42,12 @@ FlashSimBlockDevice::~FlashSimBlockDevice()
|
||||||
|
|
||||||
int FlashSimBlockDevice::init()
|
int FlashSimBlockDevice::init()
|
||||||
{
|
{
|
||||||
|
uint32_t val = core_util_atomic_incr_u32(&_init_ref_count, 1);
|
||||||
|
|
||||||
|
if (val != 1) {
|
||||||
|
return BD_ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
int ret = _bd->init();
|
int ret = _bd->init();
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -55,6 +62,12 @@ int FlashSimBlockDevice::init()
|
||||||
|
|
||||||
int FlashSimBlockDevice::deinit()
|
int FlashSimBlockDevice::deinit()
|
||||||
{
|
{
|
||||||
|
uint32_t val = core_util_atomic_decr_u32(&_init_ref_count, 1);
|
||||||
|
|
||||||
|
if (val) {
|
||||||
|
return BD_ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
return _bd->deinit();
|
return _bd->deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -135,6 +135,7 @@ private:
|
||||||
bd_size_t _blank_buf_size;
|
bd_size_t _blank_buf_size;
|
||||||
uint8_t *_blank_buf;
|
uint8_t *_blank_buf;
|
||||||
BlockDevice *_bd;
|
BlockDevice *_bd;
|
||||||
|
uint32_t _init_ref_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -15,18 +15,19 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "HeapBlockDevice.h"
|
#include "HeapBlockDevice.h"
|
||||||
|
#include "mbed_critical.h"
|
||||||
|
|
||||||
|
|
||||||
HeapBlockDevice::HeapBlockDevice(bd_size_t size, bd_size_t block)
|
HeapBlockDevice::HeapBlockDevice(bd_size_t size, bd_size_t block)
|
||||||
: _read_size(block), _program_size(block), _erase_size(block)
|
: _read_size(block), _program_size(block), _erase_size(block)
|
||||||
, _count(size / block), _blocks(0)
|
, _count(size / block), _blocks(0), _init_ref_count(0)
|
||||||
{
|
{
|
||||||
MBED_ASSERT(_count * _erase_size == size);
|
MBED_ASSERT(_count * _erase_size == size);
|
||||||
}
|
}
|
||||||
|
|
||||||
HeapBlockDevice::HeapBlockDevice(bd_size_t size, bd_size_t read, bd_size_t program, bd_size_t erase)
|
HeapBlockDevice::HeapBlockDevice(bd_size_t size, bd_size_t read, bd_size_t program, bd_size_t erase)
|
||||||
: _read_size(read), _program_size(program), _erase_size(erase)
|
: _read_size(read), _program_size(program), _erase_size(erase)
|
||||||
, _count(size / erase), _blocks(0)
|
, _count(size / erase), _blocks(0), _init_ref_count(0)
|
||||||
{
|
{
|
||||||
MBED_ASSERT(_count * _erase_size == size);
|
MBED_ASSERT(_count * _erase_size == size);
|
||||||
}
|
}
|
||||||
|
@ -45,6 +46,12 @@ HeapBlockDevice::~HeapBlockDevice()
|
||||||
|
|
||||||
int HeapBlockDevice::init()
|
int HeapBlockDevice::init()
|
||||||
{
|
{
|
||||||
|
uint32_t val = core_util_atomic_incr_u32(&_init_ref_count, 1);
|
||||||
|
|
||||||
|
if (val != 1) {
|
||||||
|
return BD_ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
if (!_blocks) {
|
if (!_blocks) {
|
||||||
_blocks = new uint8_t*[_count];
|
_blocks = new uint8_t*[_count];
|
||||||
for (size_t i = 0; i < _count; i++) {
|
for (size_t i = 0; i < _count; i++) {
|
||||||
|
@ -57,6 +64,12 @@ int HeapBlockDevice::init()
|
||||||
|
|
||||||
int HeapBlockDevice::deinit()
|
int HeapBlockDevice::deinit()
|
||||||
{
|
{
|
||||||
|
uint32_t val = core_util_atomic_decr_u32(&_init_ref_count, 1);
|
||||||
|
|
||||||
|
if (val) {
|
||||||
|
return BD_ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
MBED_ASSERT(_blocks != NULL);
|
MBED_ASSERT(_blocks != NULL);
|
||||||
// Memory is lazily cleaned up in destructor to allow
|
// Memory is lazily cleaned up in destructor to allow
|
||||||
// data to live across de/reinitialization
|
// data to live across de/reinitialization
|
||||||
|
|
|
@ -150,6 +150,7 @@ private:
|
||||||
bd_size_t _erase_size;
|
bd_size_t _erase_size;
|
||||||
bd_size_t _count;
|
bd_size_t _count;
|
||||||
uint8_t **_blocks;
|
uint8_t **_blocks;
|
||||||
|
uint32_t _init_ref_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "MBRBlockDevice.h"
|
#include "MBRBlockDevice.h"
|
||||||
|
#include "mbed_critical.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
|
||||||
|
@ -194,13 +195,19 @@ int MBRBlockDevice::partition(BlockDevice *bd, int part, uint8_t type,
|
||||||
}
|
}
|
||||||
|
|
||||||
MBRBlockDevice::MBRBlockDevice(BlockDevice *bd, int part)
|
MBRBlockDevice::MBRBlockDevice(BlockDevice *bd, int part)
|
||||||
: _bd(bd), _part(part)
|
: _bd(bd), _part(part), _init_ref_count(0)
|
||||||
{
|
{
|
||||||
MBED_ASSERT(_part >= 1 && _part <= 4);
|
MBED_ASSERT(_part >= 1 && _part <= 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
int MBRBlockDevice::init()
|
int MBRBlockDevice::init()
|
||||||
{
|
{
|
||||||
|
uint32_t val = core_util_atomic_incr_u32(&_init_ref_count, 1);
|
||||||
|
|
||||||
|
if (val != 1) {
|
||||||
|
return BD_ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
int err = _bd->init();
|
int err = _bd->init();
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
|
@ -252,6 +259,12 @@ int MBRBlockDevice::init()
|
||||||
|
|
||||||
int MBRBlockDevice::deinit()
|
int MBRBlockDevice::deinit()
|
||||||
{
|
{
|
||||||
|
uint32_t val = core_util_atomic_decr_u32(&_init_ref_count, 1);
|
||||||
|
|
||||||
|
if (val) {
|
||||||
|
return BD_ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
return _bd->deinit();
|
return _bd->deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -252,6 +252,7 @@ protected:
|
||||||
bd_size_t _size;
|
bd_size_t _size;
|
||||||
uint8_t _type;
|
uint8_t _type;
|
||||||
uint8_t _part;
|
uint8_t _part;
|
||||||
|
uint32_t _init_ref_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue