Mind Ramblings My Blog

Improving the C Interface

Hello! I am halfway through my project. I can’t say that I achieved what I aimed to, but all the things that pushed this further weren’t delays, they needed to be done. The few things that were delays taught me a lot. They were worth the effort to lay a strong foundation. It has been an amazing learning experience, and makes me even more excited for what’s to come.

Anyways, I will summarize what I did this week.

Improved C Interface

While the plan was to develop and add the feature for Integer and Rational and automating memory leak checks, it took a turn towards improving the current C interface. While writing the c wrapper code for the function SymEngine::free_symbols, the task was to transfer the information that was in C++ datatype to something in C so that is accessible in C. The return type of the C++ functions were a std::vector in one case and std::set in other. The obvious idea that came to my mind was to map them to an array of pointers that pointed to these data. This idea was also a result of us using reinterpret_cast to change the pointer type to another while transfering from C++ to C and back to C++. This was obviously not a good approach as there were too many pointers and they created very hard to correct errors in the code.

Ondrej came across this link. And suggested we adopt this method, as it was a really elegant solution for this.

The C interface now is lot more simplified. We declare the struct in the header file whereas the definition is done in the source file. The source file can indeed use C++. The header file is like this

//File: cwrapper.h
typedef struct Ctypename Ctypename;
void typename_func(Ctypename *self);

And the source file is like this

//File: cwrapper.cpp
extern "C" {

struct Ctypename {
    Cpptype data;
}

void typename_func(Ctypename *self) {
    self->data.func_call();
}

Elegant! Isn’t it?

You can find the details of our implementation by my mentor, Ondrej Certik here.

IRuby notebook

I have also prepared an IRuby notebook that will serve as a beginner notebook to get familiar with the gem. You can find it here. It contains only what the gem supports right now. I will add more notebooks as I add more features.

Checking for memory leaks

As I had mentioned in my plan for the last week, I did search for ways to automate checking for memory leaks. I have come across many tools for checking for memory leaks in Ruby, but for testing the C extensions, Valgrind and gdb are the ones that almost all of the blogs suggest. I have explained how I plan to proceed in the issue Checking Ruby C Extensions for memory leaks. #501.

It is really difficult to check for memory leaks even by ourselves, after seeing the output. I came to the conclusion that it will be very difficult to write a script that can check for memory leaks during the Continuous-Integration using Travis-CI, which was part of the initial plan. So, I have decided to automate checking of memory leaks by Valgrind and gdb from rake, and this will only ease the plan of launching the debugging session. This way developer will have to launch the tasks and manually go through the report to debug it, before pushing the code to be assured that it is free of memory leaks.

Integration of other ruby gems

I also have plans to integrate the ruby bindings for gmp, mpfr and mpc libraries, that are already available as gems, with ruby bindings for our library. I have created an issue here. Feel free to drop any suggestions.

Next week

The plan for the next week includes complete refactoring of the Ruby C API according to the new improved interface, setting up of rake tasks to detect memory leaks and add support for Integer and Rational classes.

Commits

  • Added a beginner IRuby notebook
  • Removed IRuby dependency from gemspec
  • Added the #to_iruby method
  • Added C wrapper for free_symbols
  • Added Ruby wrapper for #free_symbols
  • Added C wrapper for Basic::get_args
  • Refactored CRCPBasic in C wrappers and tests


comments powered by Disqus