Jump to content

Memory leak bug in gevent


Recommended Posts

Hello!

For example we have some code:


void clock_config(RTC_t *rtc)
{
GHandle ghFrame1;
GWidgetInit wi;
GListener cc_li;
GEvent* pe;

//Create frame
gwinWidgetClearInit(&wi);
wi.g.show = TRUE;
wi.g.width = 300;
wi.g.height = 350;
wi.g.x = (gdispGetWidth() / 2) - (wi.g.width / 2);
wi.g.y = (gdispGetHeight() / 2) - (wi.g.height / 2);
wi.text = "Date and time";
ghFrame1 = gwinFrameCreate(0, &wi, GWIN_FRAME_BORDER | GWIN_FRAME_CLOSE_BTN );

//Add another widgets and something else code....
//.......
//.......

//Create new listener
geventListenerInit(&cc_li);
gwinAttachListener(&cc_li);

// Do something...
while(1)
{
pe = geventEventWait(&cc_li, TIME_INFINITE);
switch(pe->type)
{
case GEVENT_GWIN_BUTTON:
if (((GEventGWinButton *)pe)->gwin == ghButton_Save)
{
//Exit if button pressed
geventDetachSource(&cc_li, NULL);
gwinDestroy(ghFrame1);
return;
}
break;

default:
//Exit if frame "x" button pressed
geventDetachSource(&cc_li, NULL);
//gwinDestroy(ghFrame1);
return;
}
}
}

So if we call this function and then return we lose 88 byte of heap each time a function called.

I see what in the geventListenerInit we add a semaphore to new listener:


void geventListenerInit(GListener *pl) {
gfxSemInit(&pl->waitqueue, 0, MAX_SEMAPHORE_COUNT); // Next wait'er will block
pl->callback = 0; // No callback active
pl->event.type = GEVENT_NULL; // Always safety
pl->flags = 0;
}

But this semaphore not deleted anywhere. So every call we have a new semaphore(new 88 bytes in heap).

I just put gfxSemDestroy(&pl->waitqueue) to the geventDetachSource and memory leak is gone. I know this is not right it is just for test.

I think need function some like geventListenerDeinit or we must delete this semaphore in some another place if we does not want to use created listener anymore.

Link to comment
Share on other sites

The usage case here seems a little strange.

Generally geventListenerInit is called as part of the initialisation of a program. It therefore never needs to be called again. The 88 bytes then becomes a one time overhead. Actually, the gfxSem is part of the listener structure itself so the 88 bytes must be dynamic allocation by the operating system.

In most embedded operating systems the semaphore is by structure definition rather than by handle so typically in a embedded system there is no allocation occurring at all.

Also geventDetachSource is not the opposite pair to geventListenerInit. It is the opposite pair to the geventAttachSource routine. As such it should not (and must not) destroy the mutexes at that point.

In a similar way to the use of geventListenerInit, in a real embedded device the program will never end and thus any deinit routines are just a waste of code space for objects that will survive the entire length of operation of the program (like a listener). The issue therefore with memory allocation you are seeing is unlikely to ever exist in an embedded environment both due to the operating system api specifics and due to an embedded program never ending. The issue appears to be only an artifact of the desktop emulation environment.

After said all the above, I will look at the code with the objective of cleaning up any asymmetry in the init/deinit process. It is certainly a long time since I have looked in detail at this code.

Link to comment
Share on other sites

Looking at your code more closely...

Move the geventListenerInit and the gwinAttachSource to where you do your gfxInit. The geventDetachSource call is then entirely unnecessary along with the added gfxSemDestroy. The listener will then stay ready for when you next instantiate your frame window.

Link to comment
Share on other sites

I know what I can use one listener for all function. And use geventListenerInit one time close to all init functions. I just write situation if I create new listener and want to delete it after use.

In this situations I do not have function for clear all memory used by listener. About geventDetachSource and gfxSemDestroy I written what it is just for test )

Link to comment
Share on other sites

There are a number of places in ugfx where functions designed for Init have no Deinit. This may be due to the deinit being unnecessary (say when the init does nothing but clear the object memory), or it may be that the routine has just never been written. Even some that are written do not completely clean everything up properly.

The reason for this is that these deinit routines are an after thought. In a real embedded platform they are of no use and actually take up precious code space (a real cost for no functional benefit). Tectu and I have been of differing opinions at various times about this and so any of these routines actually implemented are minimal at best.

Objects (such as mutexes and semaphores) that are commonly created and destroyed have the proper routines, it is really just routines that are considered primarily "init" time that may not not have a deinit routine.

In the next major version of ugfx I am looking to add a define that will control the explicit inclusion or exclusion of these routines and clean up much of this behaviour.

Link to comment
Share on other sites

I just say what I see when I play with uGFX. Maybe deinit functions is a real garbage as Tectu say. Or maybe some user with problem of the memory will see this topic and will know how not to do. Whos know.. :D

Link to comment
Share on other sites

Announcing the new GarbageCollection module for UGFX.

This module does everything an embedded program really wants to do but never could due to RAM constraints or code space.

Want to have a full windowing system and multi-tasking operating system on a 1K RAM ATMega?

Now you can!

Just garbage collect your program with the new ugfx module.

Currently there is one small bug - it tends to garbage collect your main user application. This short-coming is not high on our list of things to fix but will be addressed one day.

:)

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...