Monday, December 08, 2008

Onward and forward...

Progress

So I added a simple memory tracking class to the server executable (debug mode only and 32-bit at the time, it uses asm directive which is not supported in 64-bit mode so I have to come up with creative ways of accessing the 64-bit registers for the stack traces). Anyhow, it wound up being extremely useful in reporting memory leaks (since I am still working on saving up enough to buy BoundsChecker).


With OpenSSL

First one I found was in how I was cleaning up the SSL library (while most are global lifetime allocation and not really a big issue, they make the reports ugly with 600+ unallocated objects). I found various API calls to explicitly free up memory on shutdown and brought it down to only 2 leaks:

From ASocketLibrary_SSL.cpp:

ASocketLibrary_SSL::ASocketLibrary_SSL()
{
SSL_library_init();
ERR_load_crypto_strings();
SSL_load_error_strings();
}

ASocketLibrary_SSL::~ASocketLibrary_SSL()
{
ERR_remove_state(0);
ENGINE_cleanup();
CONF_modules_unload(1);
ERR_free_strings();
EVP_cleanup();
CRYPTO_cleanup_all_ex_data();
}


With GdLib

This one was actually quite serious in applications that generate dynamic images. While this is a good example where C++ destructor would have been perfect, the gdlib API is in C and thus you have o find appropriate functions to call:

From AGdCanvas.cpp:

AGdCanvas::AGdCanvas(int sx, int sy)

{
m_GdImagePtr = gdImageCreateTrueColor(sx, sy);
}

AGdCanvas::~AGdCanvas()
{
gdImageDestroy(m_GdImagePtr);
}

I was using gdFree() which unfortunately did not release the sub-objects and thus leaks a bit of memory.


Current State

At this point there are no known leaks and I ran the server under a moderate 20 client load for an hour with no variance in memory used (~30MB in full debug build, release build memory footprint is ~14MB). I disabled all caching for the test to make sure that everything was being allocated and deallocated correctly.


Miscellaneous Notes

Next version looks like it may be done this month, if I can find enough weekend time to do more testing and validation. I may rewrite the threaded queue that handles persistent sockets that are pending data of the next request, currently it uses the synchronization model from std::list and I replaced it with my home-grown ABasePtrQueue which is faster and has built-in ability to synchronize modification if given an ASynchronization object when created.


Finally

I've been spending time reading my new Lua Reference book and planning some more sample code with it. I really like Lua as a scripting language and at this point its speed and ease of embedding is tops in my list.



Overall, I was able to get majority of the sample calls to execute in AMD for that quad-core processor and dual-core processor and motherboard; made client and server with those parts and they prodly wear the "Powered by AMD" stickers!).