summaryrefslogtreecommitdiff
path: root/amiga/font.c
diff options
context:
space:
mode:
authorChris Young <chris@unsatisfactorysoftware.co.uk>2015-09-01 19:14:11 +0100
committerChris Young <chris@unsatisfactorysoftware.co.uk>2015-09-01 19:14:11 +0100
commite0198789ae1dcadbb8423478d165de60077517dc (patch)
tree414f1560d08a83ae3d069c493dcbe8fa12335dce /amiga/font.c
parent06221c23407df35c31a32309a8ef8b13b12cb417 (diff)
downloadnetsurf-e0198789ae1dcadbb8423478d165de60077517dc.tar.gz
netsurf-e0198789ae1dcadbb8423478d165de60077517dc.tar.bz2
Use a skip list instead of a splay tree for now to fix memory leakage
Diffstat (limited to 'amiga/font.c')
-rw-r--r--amiga/font.c170
1 files changed, 104 insertions, 66 deletions
diff --git a/amiga/font.c b/amiga/font.c
index 8e571048e..7569bb645 100644
--- a/amiga/font.c
+++ b/amiga/font.c
@@ -53,8 +53,6 @@
#include "amiga/object.h"
#include "amiga/schedule.h"
-#define NSA_USE_SPLAY_TREE LIB_IS_AT_LEAST((struct Library *)UtilityBase, 53, 5)
-
#define NSA_UNICODE_FONT PLOT_FONT_FAMILY_COUNT
#define NSA_NORMAL 0
@@ -74,7 +72,7 @@
struct ami_font_node
{
#ifdef __amigaos4__
- struct SplayNode *splay_node;
+ struct SkipNode skip_node;
#endif
struct OutlineFont *font;
char *bold;
@@ -151,9 +149,10 @@ const uint16 sc_table[] = {
0, 0};
#ifdef __amigaos4__
-struct SplayTree *ami_font_stree = NULL;
-#endif
+struct SkipList *ami_font_list = NULL;
+#else
struct MinList *ami_font_list = NULL;
+#endif
struct List ami_diskfontlib_list;
lwc_string *glypharray[0xffff + 1];
ULONG ami_devicedpi;
@@ -166,7 +165,6 @@ static inline int32 ami_font_width_glyph(struct OutlineFont *ofont,
const uint16 *char1, const uint16 *char2, uint32 emwidth);
static struct OutlineFont *ami_open_outline_font(const plot_font_style_t *fstyle,
const uint16 *codepoint);
-static void ami_font_cleanup(struct MinList *ami_font_list);
static inline ULONG ami_font_unicode_width(const char *string, ULONG length,
const plot_font_style_t *fstyle, ULONG x, ULONG y, bool aa);
@@ -372,15 +370,14 @@ static inline bool amiga_nsfont_split(const plot_font_style_t *fstyle,
*/
static struct ami_font_node *ami_font_open(const char *font, bool critical)
{
- struct nsObject *node;
struct ami_font_node *nodedata = NULL;
- if(NSA_USE_SPLAY_TREE) {
- nodedata = FindSplayNode(ami_font_stree, font);
- } else {
- node = (struct nsObject *)FindIName((struct List *)ami_font_list, font);
- if(node) nodedata = node->objstruct;
- }
+#ifdef __amigaos4__
+ nodedata = (struct ami_font_node *)FindSkipNode(ami_font_list, (APTR)font);
+#else
+ struct nsObject *node = (struct nsObject *)FindIName((struct List *)ami_font_list, font);
+ if(node) nodedata = node->objstruct;
+#endif
if(nodedata) {
GetSysTime(&nodedata->lastused);
@@ -389,11 +386,11 @@ static struct ami_font_node *ami_font_open(const char *font, bool critical)
LOG("Font cache miss: %s", font);
- if(NSA_USE_SPLAY_TREE) {
- nodedata = InsertSplayNode(ami_font_stree, font, sizeof(struct ami_font_node));
- } else {
- nodedata = AllocVecTagList(sizeof(struct ami_font_node), NULL);
- }
+#ifdef __amigaos4__
+ nodedata = (struct ami_font_node *)InsertSkipNode(ami_font_list, (APTR)font, sizeof(struct ami_font_node));
+#else
+ nodedata = AllocVecTagList(sizeof(struct ami_font_node), NULL);
+#endif
if(nodedata == NULL) {
warn_user("NoMemory", "");
@@ -430,13 +427,13 @@ static struct ami_font_node *ami_font_open(const char *font, bool critical)
GetSysTime(&nodedata->lastused);
- if(!NSA_USE_SPLAY_TREE) {
- node = AddObject(ami_font_list, AMINS_FONT);
- if(node) {
- node->objstruct = nodedata;
- node->dtz_Node.ln_Name = strdup(font);
- }
+#ifndef __amigaos4__
+ node = AddObject(ami_font_list, AMINS_FONT);
+ if(node) {
+ node->objstruct = nodedata;
+ node->dtz_Node.ln_Name = strdup(font);
}
+#endif
return nodedata;
}
@@ -916,52 +913,39 @@ void ami_font_savescanner(void)
ami_font_scan_save(nsoption_charp(font_unicode_file), glypharray);
}
+#ifdef __amigaos4__
static LONG ami_font_cache_sort(struct Hook *hook, APTR key1, APTR key2)
{
return stricmp(key1, key2);
}
+#endif
-void ami_init_fonts(void)
+#ifdef __amigaos4__
+static void ami_font_cleanup(struct SkipList *skiplist)
{
- /* Initialise Unicode font scanner */
- ami_font_initscanner(false, true);
-
- /* Initialise font caching etc lists */
- if(NSA_USE_SPLAY_TREE) {
- ami_font_cache_hook.h_Entry = (HOOKFUNC)ami_font_cache_sort;
- ami_font_cache_hook.h_Data = 0;
- ami_font_stree = CreateSplayTree(&ami_font_cache_hook);
- } else {
- ami_font_list = NewObjList();
- }
-
- NewList(&ami_diskfontlib_list);
-
- /* run first cleanup in ten minutes */
- if(!NSA_USE_SPLAY_TREE)
- ami_schedule(600000, (void *)ami_font_cleanup, ami_font_list);
-}
+ struct ami_font_node *node;
+ struct ami_font_node *nnode;
+ struct TimeVal curtime;
-void ami_close_fonts(void)
-{
- LOG("Cleaning up font cache");
- if(NSA_USE_SPLAY_TREE) {
- DeleteSplayTree(ami_font_stree); /** TODO: CLOSEFONTS **/
- ami_font_stree = NULL;
- } else {
- FreeObjList(ami_font_list);
- ami_font_list = NULL;
- }
- ami_font_finiscanner();
-}
+ node = (struct ami_font_node *)GetFirstSkipNode(skiplist);
+ if(node == NULL) return;
-void ami_font_close(struct ami_font_node *node)
-{
- /* Called from FreeObjList if node type is AMINS_FONT */
+ do {
+ nnode = (struct ami_font_node *)GetNextSkipNode(skiplist, (struct SkipNode *)node);
+ GetSysTime(&curtime);
+ SubTime(&curtime, &node->lastused);
+ if(curtime.Seconds > 300)
+ {
+ LOG("Freeing %s not used for %ld seconds", node->skip_node.sn_Key, curtime.Seconds);
+ ami_font_close(node);
+ RemoveSkipNode(skiplist, node->skip_node.sn_Key);
+ }
+ } while((node = nnode));
- CloseOutlineFont(node->font, &ami_diskfontlib_list);
+ /* reschedule to run in five minutes */
+ ami_schedule(300000, (void *)ami_font_cleanup, ami_font_list);
}
-
+#else
static void ami_font_cleanup(struct MinList *ami_font_list)
{
struct nsObject *node;
@@ -969,12 +953,6 @@ static void ami_font_cleanup(struct MinList *ami_font_list)
struct ami_font_node *fnode;
struct TimeVal curtime;
- /** TODO **/
- if(NSA_USE_SPLAY_TREE) {
- return;
- }
- /****/
-
if(IsMinListEmpty(ami_font_list)) return;
node = (struct nsObject *)GetHead((struct List *)ami_font_list);
@@ -995,6 +973,66 @@ static void ami_font_cleanup(struct MinList *ami_font_list)
/* reschedule to run in five minutes */
ami_schedule(300000, (void *)ami_font_cleanup, ami_font_list);
}
+#endif
+
+void ami_init_fonts(void)
+{
+ /* Initialise Unicode font scanner */
+ ami_font_initscanner(false, true);
+
+ /* Initialise font caching etc lists */
+#ifdef __amigaos4__
+ ami_font_cache_hook.h_Entry = (HOOKFUNC)ami_font_cache_sort;
+ ami_font_cache_hook.h_Data = 0;
+ ami_font_list = CreateSkipList(&ami_font_cache_hook, 8);
+#else
+ ami_font_list = NewObjList();
+#endif
+
+ NewList(&ami_diskfontlib_list);
+
+ /* run first cleanup in ten minutes */
+ ami_schedule(600000, (void *)ami_font_cleanup, ami_font_list);
+}
+
+#ifdef __amigaos4__
+static void ami_font_del_skiplist(struct SkipList *skiplist)
+{
+ struct SkipNode *node;
+ struct SkipNode *nnode;
+
+ node = GetFirstSkipNode(skiplist);
+ if(node == NULL) return;
+
+ do {
+ nnode = GetNextSkipNode(skiplist, node);
+ ami_font_close((struct ami_font_node *)node);
+
+ } while((node = nnode));
+
+ DeleteSkipList(skiplist);
+}
+#endif
+
+void ami_close_fonts(void)
+{
+ LOG("Cleaning up font cache");
+ ami_schedule(-1, (void *)ami_font_cleanup, ami_font_list);
+#ifdef __amigaos4__
+ ami_font_del_skiplist(ami_font_list);
+#else
+ FreeObjList(ami_font_list);
+#endif
+ ami_font_list = NULL;
+ ami_font_finiscanner();
+}
+
+void ami_font_close(struct ami_font_node *node)
+{
+ /* Called from FreeObjList if node type is AMINS_FONT */
+
+ CloseOutlineFont(node->font, &ami_diskfontlib_list);
+}
void ami_font_setdevicedpi(int id)
{