mirror of
https://github.com/netsurf-browser/netsurf
synced 2024-12-23 12:36:51 +03:00
AmigaOS low memory handler attempt 2
Neither freeing slabs nor purging the cache are safe to call from interrupts, so instead we schedule these to run on NetSurf's process. If NetSurf is busy, there may be significant delay, so the priority is set low to ensure this is called only when other - faster - memory handlers have been exhausted. I don't know if this works, or is sane, as I'm not entirely sure how to test it. Something similar needs adding for OS4 but low memory is less of an issue there, so will see if this works on OS3 first.
This commit is contained in:
parent
a76a36915c
commit
4fb38f574a
@ -22,10 +22,21 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "amiga/memory.h"
|
#include "amiga/memory.h"
|
||||||
#include "amiga/os3support.h"
|
#include "amiga/os3support.h"
|
||||||
|
#include "amiga/schedule.h"
|
||||||
|
#include "content/llcache.h"
|
||||||
#include "utils/log.h"
|
#include "utils/log.h"
|
||||||
|
|
||||||
ULONG __slab_max_size = 2048; /* Enable clib2's slab allocator */
|
ULONG __slab_max_size = 2048; /* Enable clib2's slab allocator */
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PURGE_NONE = 0,
|
||||||
|
PURGE_STEP1,
|
||||||
|
PURGE_STEP2,
|
||||||
|
PURGE_DONE_STEP1,
|
||||||
|
PURGE_DONE_STEP2
|
||||||
|
};
|
||||||
|
static int low_mem_status = PURGE_NONE;
|
||||||
|
|
||||||
/* Special clear (ie. non-zero) */
|
/* Special clear (ie. non-zero) */
|
||||||
void *ami_memory_clear_alloc(size_t size, UBYTE value)
|
void *ami_memory_clear_alloc(size_t size, UBYTE value)
|
||||||
{
|
{
|
||||||
@ -64,11 +75,39 @@ void ami_memory_slab_dump(void)
|
|||||||
__get_slab_usage(ami_memory_slab_callback);
|
__get_slab_usage(ami_memory_slab_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ami_memory_low_mem_handler(void *p)
|
||||||
|
{
|
||||||
|
if(low_mem_status == PURGE_STEP1) {
|
||||||
|
LOG("Purging llcache");
|
||||||
|
llcache_clean(true);
|
||||||
|
low_mem_status = PURGE_DONE_STEP1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(low_mem_status == PURGE_STEP2) {
|
||||||
|
LOG("Purging unused slabs");
|
||||||
|
__free_unused_slabs();
|
||||||
|
low_mem_status = PURGE_DONE_STEP2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static ASM ULONG ami_memory_handler(REG(a0, struct MemHandlerData *mhd), REG(a1, void *userdata), REG(a6, struct ExecBase *execbase))
|
static ASM ULONG ami_memory_handler(REG(a0, struct MemHandlerData *mhd), REG(a1, void *userdata), REG(a6, struct ExecBase *execbase))
|
||||||
{
|
{
|
||||||
__free_unused_slabs();
|
if(low_mem_status == PURGE_DONE_STEP2) {
|
||||||
|
low_mem_status = PURGE_NONE;
|
||||||
|
return MEM_ALL_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
return MEM_ALL_DONE;
|
if(low_mem_status == PURGE_DONE_STEP1) {
|
||||||
|
low_mem_status = PURGE_STEP2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(low_mem_status == PURGE_NONE) {
|
||||||
|
low_mem_status = PURGE_STEP1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ami_schedule(1, ami_memory_low_mem_handler, NULL);
|
||||||
|
|
||||||
|
return MEM_TRY_AGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Interrupt *ami_memory_init(void)
|
struct Interrupt *ami_memory_init(void)
|
||||||
@ -76,8 +115,8 @@ struct Interrupt *ami_memory_init(void)
|
|||||||
struct Interrupt *memhandler = malloc(sizeof(struct Interrupt));
|
struct Interrupt *memhandler = malloc(sizeof(struct Interrupt));
|
||||||
if(memhandler == NULL) return NULL; // we're screwed
|
if(memhandler == NULL) return NULL; // we're screwed
|
||||||
|
|
||||||
memhandler->is_Node.ln_Pri = 1;
|
memhandler->is_Node.ln_Pri = -100; // low down as will be slow
|
||||||
memhandler->is_Node.ln_Name = "NetSurf slab memory handler";
|
memhandler->is_Node.ln_Name = "NetSurf low memory handler";
|
||||||
memhandler->is_Data = NULL;
|
memhandler->is_Data = NULL;
|
||||||
memhandler->is_Code = (APTR)&ami_memory_handler;
|
memhandler->is_Code = (APTR)&ami_memory_handler;
|
||||||
AddMemHandler(memhandler);
|
AddMemHandler(memhandler);
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#ifndef AMIGA_SCHEDULE_H
|
#ifndef AMIGA_SCHEDULE_H
|
||||||
#define AMIGA_SCHEDULE_H
|
#define AMIGA_SCHEDULE_H
|
||||||
#include "amiga/os3support.h"
|
#include "amiga/os3support.h"
|
||||||
|
#include "utils/errors.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Schedule a callback.
|
* Schedule a callback.
|
||||||
|
Loading…
Reference in New Issue
Block a user