Add init reference count to all block devices

pull/7753/head
David Saada 2018-07-30 19:37:15 +03:00 committed by adbridge
parent 57bd7109f8
commit a709e91920
13 changed files with 96 additions and 12 deletions

View File

@ -92,10 +92,6 @@ void test_slicing() {
TEST_ASSERT_EQUAL(0xff & rand(), read_block[i]);
}
err = slice1.deinit();
TEST_ASSERT_EQUAL(0, err);
// Test with second slice of block device
err = slice2.init();
TEST_ASSERT_EQUAL(0, err);
@ -109,6 +105,10 @@ void test_slicing() {
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
err = slice2.program(write_block, 0, BLOCK_SIZE);
TEST_ASSERT_EQUAL(0, err);

View File

@ -16,6 +16,7 @@
#include "BufferedBlockDevice.h"
#include "mbed_assert.h"
#include "mbed_critical.h"
#include <algorithm>
#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)
: _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()
{
uint32_t val = core_util_atomic_incr_u32(&_init_ref_count, 1);
if (val != 1) {
return BD_ERROR_OK;
}
int err = _bd->init();
if (err) {
return err;
@ -55,6 +62,12 @@ int BufferedBlockDevice::init()
int BufferedBlockDevice::deinit()
{
uint32_t val = core_util_atomic_decr_u32(&_init_ref_count, 1);
if (val) {
return BD_ERROR_OK;
}
delete[] _cache;
_cache = 0;
return _bd->deinit();

View File

@ -153,6 +153,7 @@ protected:
bd_size_t _curr_aligned_addr;
bool _flushed;
uint8_t *_cache;
uint32_t _init_ref_count;
/** Flush data in cache
*

View File

@ -15,12 +15,13 @@
*/
#include "ChainingBlockDevice.h"
#include "mbed_critical.h"
ChainingBlockDevice::ChainingBlockDevice(BlockDevice **bds, size_t bd_count)
: _bds(bds), _bd_count(bd_count)
, _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()
{
uint32_t val = core_util_atomic_incr_u32(&_init_ref_count, 1);
if (val != 1) {
return BD_ERROR_OK;
}
_read_size = 0;
_program_size = 0;
_erase_size = 0;
@ -83,6 +90,12 @@ int ChainingBlockDevice::init()
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++) {
int err = _bds[i]->deinit();
if (err) {

View File

@ -64,7 +64,7 @@ public:
template <size_t Size>
ChainingBlockDevice(BlockDevice *(&bds)[Size])
: _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 _size;
int _erase_value;
uint32_t _init_ref_count;
};

View File

@ -16,10 +16,11 @@
#include "ExhaustibleBlockDevice.h"
#include "mbed.h"
#include "mbed_critical.h"
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()
{
uint32_t val = core_util_atomic_incr_u32(&_init_ref_count, 1);
if (val != 1) {
return BD_ERROR_OK;
}
int err = _bd->init();
if (err) {
return err;
@ -48,6 +55,12 @@ int ExhaustibleBlockDevice::init()
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
// data to live across de/reinitialization
return _bd->deinit();

View File

@ -154,6 +154,7 @@ private:
BlockDevice *_bd;
uint32_t *_erase_array;
uint32_t _erase_cycles;
uint32_t _init_ref_count;
};

View File

@ -16,6 +16,7 @@
#include "FlashSimBlockDevice.h"
#include "mbed_assert.h"
#include "mbed_critical.h"
#include <algorithm>
#include <stdlib.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) :
_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()
{
uint32_t val = core_util_atomic_incr_u32(&_init_ref_count, 1);
if (val != 1) {
return BD_ERROR_OK;
}
int ret = _bd->init();
if (ret) {
return ret;
@ -55,6 +62,12 @@ int FlashSimBlockDevice::init()
int FlashSimBlockDevice::deinit()
{
uint32_t val = core_util_atomic_decr_u32(&_init_ref_count, 1);
if (val) {
return BD_ERROR_OK;
}
return _bd->deinit();
}

View File

@ -135,6 +135,7 @@ private:
bd_size_t _blank_buf_size;
uint8_t *_blank_buf;
BlockDevice *_bd;
uint32_t _init_ref_count;
};
#endif

View File

@ -15,18 +15,19 @@
*/
#include "HeapBlockDevice.h"
#include "mbed_critical.h"
HeapBlockDevice::HeapBlockDevice(bd_size_t size, bd_size_t 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);
}
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)
, _count(size / erase), _blocks(0)
, _count(size / erase), _blocks(0), _init_ref_count(0)
{
MBED_ASSERT(_count * _erase_size == size);
}
@ -45,6 +46,12 @@ HeapBlockDevice::~HeapBlockDevice()
int HeapBlockDevice::init()
{
uint32_t val = core_util_atomic_incr_u32(&_init_ref_count, 1);
if (val != 1) {
return BD_ERROR_OK;
}
if (!_blocks) {
_blocks = new uint8_t*[_count];
for (size_t i = 0; i < _count; i++) {
@ -57,6 +64,12 @@ int HeapBlockDevice::init()
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);
// Memory is lazily cleaned up in destructor to allow
// data to live across de/reinitialization

View File

@ -150,6 +150,7 @@ private:
bd_size_t _erase_size;
bd_size_t _count;
uint8_t **_blocks;
uint32_t _init_ref_count;
};

View File

@ -15,6 +15,7 @@
*/
#include "MBRBlockDevice.h"
#include "mbed_critical.h"
#include <algorithm>
@ -194,13 +195,19 @@ int MBRBlockDevice::partition(BlockDevice *bd, int part, uint8_t type,
}
MBRBlockDevice::MBRBlockDevice(BlockDevice *bd, int part)
: _bd(bd), _part(part)
: _bd(bd), _part(part), _init_ref_count(0)
{
MBED_ASSERT(_part >= 1 && _part <= 4);
}
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();
if (err) {
return err;
@ -252,6 +259,12 @@ int MBRBlockDevice::init()
int MBRBlockDevice::deinit()
{
uint32_t val = core_util_atomic_decr_u32(&_init_ref_count, 1);
if (val) {
return BD_ERROR_OK;
}
return _bd->deinit();
}

View File

@ -252,6 +252,7 @@ protected:
bd_size_t _size;
uint8_t _type;
uint8_t _part;
uint32_t _init_ref_count;
};