Monday, December 9, 2019

Commence the Porting

After a month of research and getting used to the Gateware environment, I've finally been tasked to start working in the new architecture. My first job has been to write unit tests for some of the existing libraries for the new system, I chose to go with GThreadShared. This library is a wrapper for mutex and SRWLocks which allow the user to lock and unlock either read or write critical sections. The first couple tests written are just battery tests to make sure inheritance is working as expected, the second set of tests will be testing the functionality of the locking mechanisms. If all goes well over the next few days, I might be honored with the task to write the unit tests for multi-threading libraries that the Gateware developers will be using for their libraries.

Friday, December 6, 2019

When a project becomes a hydra you have to know how to trim its heads (GCollision Unit Test Phase)

Writing a library for Gateware can be a task that may seem vast and steep. Previously, I had discussed the monstrous interface I created for the Gateware GCollision library and now I will discuss the challenge with it going into the next stage of creating this library which is: dummy unit tests. The GCollision currently has about 1950 functions, but a lot of them are the same functionality overloaded. I imagine about a fifth of that or less are somewhat unique functions. It's a bit hard to tell at the moment because even then it's quite overwhelming, but no matter how trivial some of these maybe they still require unit tests. With each unit test possibly requiring multiple positive and negative tests, you're now looking at a hydra of a project. So, where do we go from here?

I shared my update with the lead software architect, Lari, and he was easily able to suggest the solution to ensure this library will be complete within time. Prioritize completing the unit tests and functions that will most likely be the most used by the users. I know it seems obvious, but I had researched this for a month prior to this step and every function and geometrical representation that I chose had become one of my babies. I didn't want to abandon any of them. Lari had less attachment to them and his suggestion is more realistic. I'm also more healthier now that I can work on batches of the library instead of spending who knows how many man-hours writing unit tests before I even get a function going. Below is a table of the first priority batch which is the test if two objects are touching or not from the shapes: point to OBB.


Thursday, December 5, 2019

GAudio/GAudio3D on Mac (Objective-C memory management)

Month: 2, Week: 2

This month I jumped straight into debugging and identifying issues with GAudio and GAudio3D libraries on Linux and Mac (I fixed Windows side last month). My main task for the last couple of days was attempting to port Windows fix directly to other platforms. And this is not as easy as it sounds.


I started with Linux and made some changes, but I could not gain much information due to a steep learning curve on Valgrind (and CMake). I explored both Linux and Mac code bases and decided to focus on Mac first, as I had access to Mac only in the office.


I never worked on Mac before, so XCode, Mac UI and Objective-C were foreign to me but it was not too bad. I implemented my Windows fixes, and while it fixed the issues on C++ side, it did not fix any of the memory leaks that were caused by Objective-C objects. I found a solution but it was a dangerous one. Later that day I came across a very clean and detailed post about Objective-C memory management which made me realize that my solution is very error-prone. I rewrote the cleanup code, refactored some functions and now GAudio/GAudio3D libraries on Mac are not leaking memory and stable.


"So now the question becomes "how long can I safely use the object before the autorelease pool is drained?" In Cocoa, the pool is drained after every NSEvent is sent. For example, if the user clicks the mouse twice then the pool will be drained in between the first and the second click. This is why it is safe to use an object temporarily, but it is not safe to keep an object unless you own it. If you don't retain your ivar and the user moves her mouse, suddenly your ivar is gone and you're probably going to crash very shortly."

Objective-C Memory Management post: https://www.tomdalling.com/blog/cocoa/an-in-depth-look-at-manual-memory-management-in-objective-c/

Now I am moving back to Linux with a better understanding of GAudio, Valgrind and CMake. It should be pretty a straight forward fix, unless I run into multi-threading problems with Pulse audio (Linux), like I did with XAudio2 on Windows.









Starting the Port


This month we get to start the porting job and I'm excited about it. Learning how to make unit tests has been a fun adventure since the last time I wrote some unit tests was in PG2. Not alot has really happened I'm just super excited to start the meat of the porting process

Linux is strange

Over the last week I've been digging deep into GWindow on Linux to find and correct memory leaks that were pretty wound into it. Plus it all being on Linux meant some strange complpications came into place, such as spending a day proving that the library was the source of a leak only for me to be unable to replicate the error the very next day. All that combined with the sheer quantity of memory leaks made it difficult to trace case by case instances and so I struggled.

As I continued over the week I found myself getting more and more accustomed to the memory leak tool valgrind and reading it got easier. I learned new functionality for it that allowed me to trace problems more specifically and started getting a more solid idea of just how GWindow's functionality is implemented and where the inconsistent pieces were. It turned out that Linux's event system used a different heirarchy than Windows or Mac and so threads were being launched but never checked on again. From that point I was able to start cleaning up small leaks and on the same path found a way to stop the vast majority of Linux's GWindow leaks. In my solution with only GWindow enabled there were still two leaks left to handle, one not relating to GWindow, but I have a new assignment now so they'll wait another little bit yet.


Unit Tests for new GatewareX interfaces

I begun writing unit tests for GEvent interfaces: GEvent, GEventGenerator, GEventReceiver, and GEventQueue using catch2 which is an open source header-only framework for creating unit tests. Here are some code:
TEST_CASE("GEventGenerator core method test battery")
{
GW::GReturn gr;
GW::CORE::GInterface emptyInterface;

unsigned int listenerCount = 0;

GW::CORE::GEventGenerator eventGenerator;
SECTION("Testing Empty proxy method calls")
{
REQUIRE(eventGenerator.Observers(listenerCount) == GW::GReturn::EMPTY_PROXY);
REQUIRE(eventGenerator.Push(GW::GEvent()) == GW::GReturn::EMPTY_PROXY);
REQUIRE(eventGenerator.Register(emptyInterface, nullptr) == GW::GReturn::EMPTY_PROXY);
}

SECTION("Testing Creation/Destruction method calls")
{
REQUIRE(eventGenerator.Create() == GW::GReturn::SUCCESS);
REQUIRE(eventGenerator);
eventGenerator = nullptr;
REQUIRE(!eventGenerator);
REQUIRE(eventGenerator.Create() == GW::GReturn::SUCCESS);
}

// Now we can begin checking valid proxy method calls
REQUIRE(eventGenerator.Create() == GW::GReturn::SUCCESS);
SECTION("Testing Valid proxy method calls")
{
REQUIRE(+eventGenerator.Observers(listenerCount));
REQUIRE(+eventGenerator.Push(GW::GEvent()));
CHECK(+eventGenerator.Register(emptyInterface, nullptr));
REQUIRE(+emptyInterface.Create());
}
}

So far I've been pretty successful on writing new unit tests, the biggest thing here is that debugging through the unit tests gives me more understanding of the new event system. Which I will have to tell Chris about so he can document on it.

Monday, December 2, 2019

Hello

My name is Jadon Lindburg and I will be working on 2D rendering.