buflib: add a common dummy callbacks struct & use it
There are various allocations that can't be moved or shrunk. Provide a global callback struct for this use case instead of making each caller declare its own dummy struct. Also fixed ROLO and x1000 installer code which incorrectly used movable allocations. Change-Id: I00088396b9826e02e69a4a33477fe1a7816374f1
This commit is contained in:
parent
95dfc489b5
commit
e8faf2f2ad
14 changed files with 43 additions and 30 deletions
|
@ -2076,13 +2076,10 @@ int playlist_create(const char *dir, const char *file)
|
|||
|
||||
if (file)
|
||||
{
|
||||
/* dummy ops with no callbacks, needed because by
|
||||
* default buflib buffers can be moved around which must be avoided */
|
||||
static struct buflib_callbacks dummy_ops;
|
||||
int handle;
|
||||
size_t buflen;
|
||||
/* use mp3 buffer for maximum load speed */
|
||||
handle = core_alloc_maximum("temp", &buflen, &dummy_ops);
|
||||
handle = core_alloc_maximum("temp", &buflen, &buflib_ops_locked);
|
||||
if (handle > 0)
|
||||
{
|
||||
/* load the playlist file */
|
||||
|
@ -2119,13 +2116,10 @@ int playlist_resume(void)
|
|||
bool sorted = true;
|
||||
int result = -1;
|
||||
|
||||
/* dummy ops with no callbacks, needed because by
|
||||
* default buflib buffers can be moved around which must be avoided */
|
||||
static struct buflib_callbacks dummy_ops;
|
||||
/* use mp3 buffer for maximum load speed */
|
||||
if (core_allocatable() < (1 << 10))
|
||||
talk_buffer_set_policy(TALK_BUFFER_LOOSE); /* back off voice buffer */
|
||||
handle = core_alloc_maximum("temp", &buflen, &dummy_ops);
|
||||
handle = core_alloc_maximum("temp", &buflen, &buflib_ops_locked);
|
||||
if (handle < 0)
|
||||
{
|
||||
splashf(HZ * 2, "%s(): OOM", __func__);
|
||||
|
|
|
@ -990,14 +990,11 @@ void* plugin_get_buffer(size_t *buffer_size)
|
|||
*/
|
||||
static void* plugin_get_audio_buffer(size_t *buffer_size)
|
||||
{
|
||||
/* dummy ops with no callbacks, needed because by
|
||||
* default buflib buffers can be moved around which must be avoided */
|
||||
static struct buflib_callbacks dummy_ops;
|
||||
if (plugin_buffer_handle <= 0)
|
||||
{
|
||||
plugin_buffer_handle = core_alloc_maximum("plugin audio buf",
|
||||
&plugin_buffer_size,
|
||||
&dummy_ops);
|
||||
&buflib_ops_locked);
|
||||
}
|
||||
|
||||
if (buffer_size)
|
||||
|
|
|
@ -1406,12 +1406,9 @@ static int pcmrec_handle;
|
|||
static void on_init_recording(void)
|
||||
{
|
||||
send_event(RECORDING_EVENT_START, NULL);
|
||||
/* dummy ops with no callbacks, needed because by
|
||||
* default buflib buffers can be moved around which must be avoided
|
||||
* FIXME: This buffer should play nicer and be shrinkable/movable */
|
||||
static struct buflib_callbacks dummy_ops;
|
||||
/* FIXME: This buffer should play nicer and be shrinkable/movable */
|
||||
talk_buffer_set_policy(TALK_BUFFER_LOOSE);
|
||||
pcmrec_handle = core_alloc_maximum("pcmrec", &rec_buffer_size, &dummy_ops);
|
||||
pcmrec_handle = core_alloc_maximum("pcmrec", &rec_buffer_size, &buflib_ops_locked);
|
||||
if (pcmrec_handle <= 0)
|
||||
/* someone is abusing core_alloc_maximum(). Fix this evil guy instead of
|
||||
* trying to handle OOM without hope */
|
||||
|
|
|
@ -328,8 +328,7 @@ static void allocate_tempbuf(void)
|
|||
#else /* !__PCTOOL__ */
|
||||
/* Need to pass dummy ops to prevent the buffer being moved
|
||||
* out from under us, since we yield during the tagcache commit. */
|
||||
static struct buflib_callbacks dummy_ops;
|
||||
tempbuf_handle = core_alloc_maximum("tc tempbuf", &size, &dummy_ops);
|
||||
tempbuf_handle = core_alloc_maximum("tc tempbuf", &size, &buflib_ops_locked);
|
||||
if (tempbuf_handle > 0)
|
||||
{
|
||||
tempbuf = core_get_data(tempbuf_handle);
|
||||
|
|
|
@ -97,6 +97,12 @@
|
|||
|
||||
#define BPANICF panicf
|
||||
|
||||
struct buflib_callbacks buflib_ops_locked = {
|
||||
.move_callback = NULL,
|
||||
.shrink_callback = NULL,
|
||||
.sync_callback = NULL,
|
||||
};
|
||||
|
||||
#define IS_MOVABLE(a) (!a[2].ops || a[2].ops->move_callback)
|
||||
static union buflib_data* find_first_free(struct buflib_context *ctx);
|
||||
static union buflib_data* find_block_before(struct buflib_context *ctx,
|
||||
|
|
|
@ -32,9 +32,7 @@
|
|||
#include "crc32.h"
|
||||
#include "rbendian.h"
|
||||
|
||||
#define zip_core_alloc(N) core_alloc_ex("zip",(N),&dummy_ops)
|
||||
|
||||
static struct buflib_callbacks dummy_ops;
|
||||
#define zip_core_alloc(N) core_alloc_ex("zip",(N),&buflib_ops_locked)
|
||||
|
||||
enum {
|
||||
ZIP_SIG_ED = 0x06054b50,
|
||||
|
|
|
@ -129,6 +129,12 @@ struct buflib_callbacks {
|
|||
void (*sync_callback)(int handle, bool sync_on);
|
||||
};
|
||||
|
||||
/** A set of all NULL callbacks for use with allocations that need to stay
|
||||
* locked in RAM and not moved or shrunk. These type of allocations should
|
||||
* be avoided as much as possible to avoid memory fragmentation but it can
|
||||
* suitable for short-lived allocations. */
|
||||
extern struct buflib_callbacks buflib_ops_locked;
|
||||
|
||||
#define BUFLIB_SHRINK_SIZE_MASK (~BUFLIB_SHRINK_POS_MASK)
|
||||
#define BUFLIB_SHRINK_POS_FRONT (1u<<31)
|
||||
#define BUFLIB_SHRINK_POS_BACK (1u<<30)
|
||||
|
|
|
@ -242,7 +242,7 @@ int rolo_load(const char* filename)
|
|||
|
||||
/* get the system buffer. release only in case of error, otherwise
|
||||
* we don't return anyway */
|
||||
rolo_handle = core_alloc_maximum("rolo", &filebuf_size, NULL);
|
||||
rolo_handle = core_alloc_maximum("rolo", &filebuf_size, &buflib_ops_locked);
|
||||
if (rolo_handle < 0)
|
||||
{
|
||||
rolo_error("OOM");
|
||||
|
|
|
@ -148,7 +148,7 @@ static int updater_init(struct updater* u)
|
|||
|
||||
/* buf_len is a bit oversized here, but it's not really important */
|
||||
u->buf_len = u->img_len + sizeof(mtar_t) + 2*CACHEALIGN_SIZE;
|
||||
u->buf_hnd = core_alloc("boot_image", u->buf_len);
|
||||
u->buf_hnd = core_alloc_ex("boot_image", u->buf_len, &buflib_ops_locked);
|
||||
if(u->buf_hnd < 0) {
|
||||
rc = IERR_OUT_OF_MEMORY;
|
||||
goto error;
|
||||
|
|
|
@ -449,12 +449,11 @@ void usb_storage_init_connection(void)
|
|||
#endif
|
||||
#else
|
||||
unsigned char * buffer;
|
||||
/* dummy ops with no callbacks, needed because by
|
||||
* default buflib buffers can be moved around which must be avoided */
|
||||
static struct buflib_callbacks dummy_ops;
|
||||
|
||||
// Add 31 to handle worst-case misalignment
|
||||
usb_handle = core_alloc_ex("usb storage", ALLOCATE_BUFFER_SIZE + MAX_CBW_SIZE + 31, &dummy_ops);
|
||||
usb_handle = core_alloc_ex("usb storage",
|
||||
ALLOCATE_BUFFER_SIZE + MAX_CBW_SIZE + 31,
|
||||
&buflib_ops_locked);
|
||||
if (usb_handle < 0)
|
||||
panicf("%s(): OOM", __func__);
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ int xf_nandio_init(struct xf_nandio* nio)
|
|||
alloc_size += CACHEALIGN_SIZE - 1;
|
||||
alloc_size += nio->block_size * 2;
|
||||
|
||||
nio->alloc_handle = core_alloc("xf_nandio", alloc_size);
|
||||
nio->alloc_handle = core_alloc_ex("xf_nandio", alloc_size, &buflib_ops_locked);
|
||||
if(nio->alloc_handle < 0) {
|
||||
rc = XF_E_OUT_OF_MEMORY;
|
||||
goto out_nclose;
|
||||
|
|
|
@ -49,7 +49,7 @@ static int pkg_alloc(struct xf_package* pkg)
|
|||
alloc_size += ALIGN_UP_P2(METADATA_SIZE, 3);
|
||||
alloc_size += 7; /* for alignment */
|
||||
|
||||
pkg->alloc_handle = core_alloc("xf_package", alloc_size);
|
||||
pkg->alloc_handle = core_alloc_ex("xf_package", alloc_size, &buflib_ops_locked);
|
||||
if(pkg->alloc_handle < 0)
|
||||
return XF_E_OUT_OF_MEMORY;
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#define N_POINTERS 100
|
||||
|
||||
static void* pointers[N_POINTERS];
|
||||
struct buflib_callbacks buflib_ops_locked = {NULL, NULL, NULL};
|
||||
|
||||
int core_alloc(const char* name, size_t size)
|
||||
{
|
||||
|
@ -46,6 +47,12 @@ int core_alloc(const char* name, size_t size)
|
|||
return -1;
|
||||
}
|
||||
|
||||
int core_alloc_ex(const char* name, size_t size, struct buflib_callbacks* cb)
|
||||
{
|
||||
(void)cb;
|
||||
return core_alloc(name, size);
|
||||
}
|
||||
|
||||
int core_free(int handle)
|
||||
{
|
||||
if(handle > 0) {
|
||||
|
|
|
@ -25,8 +25,18 @@
|
|||
#define CORE_ALLOC_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
struct buflib_callbacks {
|
||||
int (*move_callback)(int handle, void* current, void* new);
|
||||
int (*shrink_callback)(int handle, unsigned hints, void* start, size_t old_size);
|
||||
void (*sync_callback)(int handle, bool sync_on);
|
||||
};
|
||||
|
||||
extern struct buflib_callbacks buflib_ops_locked;
|
||||
|
||||
int core_alloc(const char* name, size_t size);
|
||||
int core_alloc_ex(const char* name, size_t size, struct buflib_callbacks* cb);
|
||||
int core_free(int handle);
|
||||
void* core_get_data(int handle);
|
||||
|
||||
|
|
Loading…
Reference in a new issue