Archive for the ‘Coding’ Category

Added Source and Sink Template Classes to DKit

Friday, May 11th, 2012

DKit Laboratory

Today I wanted to add a little bit more to DKit, so I decided that the next best thing to add were the concepts of a template source and sink. When I built the MessageSource and MessageSink back at PEAK6, I did it in the context of a Message object. That was fine, because that's all we needed, but this time I wanted to make it a little better - no a lot better, so I made the source and sink template classes.

This will allow me to use the pointers like I did before, but it will also make it very easy to use integers, or doubles - or anything. This will be a far better solution to the problem than a fixed class, or pointer to a class.

The only real problem I ran into - if there was indeed any real problems, was the syntax for specifying the template class methods in the implementation file. The header was pretty clear and straight forward, but the implementation was a bit trickier.

Thankfully, I was able to find some examples on the web, but the syntax was pretty bad. I mean really bad. For example, let's say I had the following template class:

  namespace dkit {
  template <class T> class source
  {
    public:
 
      virtual void setName( const std::string & aName );
      virtual const std::string & getName() const;
      virtual bool addToListeners( sink<T> *aSink );
 
  };
  }     // end of namespace dkit

then the implementation file would have to look something like this:

  namespace dkit {
 
  template <class T> void source<T>::setName( const std::string & aName )
  {
    boost::detail::spinlock::scoped_lock  lock(mMutex);
    mName = aName;
  }
 
 
  template <class T> const std::string & source<T>::getName() const
  {
    return mName;
  }
 
 
  template <class T> bool source<T>::addToListeners( sink<T> *aSink )
  {
    bool       added = false;
    // first, make sure there's something to do
    if (aSink != NULL) {
      // next, see if we can add us as a source to him
      if (aSink->addToSources(this)) {
        // finally, make sure we can add him to us
        added = addToSinks(aSink);
      }
    }
    return added;
  }
 
  }     // end of namespace dkit

Now I understand the need to clearly identify the class - hence the template <class T> on the front, but then it seems to really go overboard there. While I'm sure there's a wonderful reason for all this, it seems to have not undergone any simplification over the years. That's probably part of the problem that folks have with C++ - it's complicated looking. And if you don't get it just right, you're not going to even get it to compile.

But for me, it's just what has to be done in order to have template programming. It's a pain, yes, but it's so incredibly worth it.

Looking at C++ Unit Testing Frameworks

Thursday, May 10th, 2012

bug.gif

I've used JUnit and the Unit Testing Framework in Xcode 4, and both are pretty nice - they allow you to write tests, not headers and a lot of boilerplate code. Just the tests. Lots of simple assertions and tests, and it's really not bad at all to use these guys. But with C++ I'm finding it a lot harder to start using a testing framework. Maybe it's me, maybe it's just the language, but it's not a lot less than writing test apps, and having explicit return codes.

I'm not saying that testing isn't useful, what I'm wondering is if C++ as a language is really set up to have a nice, simple, unit testing framework like JUnit or SenTesting Framework. After all, there's a lot of flexibility in Java and Obj-C that simply isn't in C++. You can add methods to Java and Obj-C in the implementation file and run with it. Reflection (introspection) allows the language and framework to see what's available to run, and then run it. Not so for C++.

So I'm wondering if there's really any better solution than a series of good testing apps with proper return codes, and then you just run one after the other until you have what you need. Not ideal, to be sure, and it takes some effort and discipline to make sure the test apps are done properly, but I just don't see a way to make it happen in a significantly easier way.

I'll keep looking, though. Maybe someone is going to crack this nut soon.

Fun with Boost and DKit

Thursday, May 10th, 2012

DKit Laboratory

This morning I finished up a little coding I was doing on DKit and was really happy about the outcome. The thing that really set the stage was the building of boost for OS X 10.7. It was really pretty simple, and it allows me the flexibility to use boost in DKit. Now there was nothing really stopping me before, but without it running on my MacBook Pro, it was a little hard to know that it was going to work.

I suppose I could have pulled out my old Intel laptop and downloaded Ubuntu 12 and put it on there, and run it in a terminal, but I didn't really feel like bring that guy out of the closet, but maybe it's time. I could really use to have Ubuntu 12 working now.

In any case, boost is built, and I was able to make the "hammer" and "drain" thread tests on the LinkedFIFO queues. The idea is that I have a "hammer" that can place items on a queue, and then a drain that can empty a queue. By putting these in different combinations, I can test a multi-producer/single-consumer queue as well as a single-producer/multi-consumer queue.

Starting with the Right Base Class

One of the neat things I did this morning was to make a base abstract template class for all the FIFO queues, as they all (on purpose) have the same basic API. This then allows me to treat all the different implementations as just that - implementations and not as something of significant difference.

It's not too exciting, but I was pretty pleased after I had created it and then used it as the base class for all the FIFO implementations I had in DKit. The really important part was to make sure that the core API methods were pure virtual methods - a.k.a. virtual abstract methods:

  /*******************************************************************
   *
   *                        Accessor Methods
   *
   *******************************************************************/
  /**
   * This method takes an item and places it in the queue - if it can.
   * If so, then it will return 'true', otherwise, it'll return 'false'.
   */
  virtual bool push( const T & anElem ) = 0;
  /**
   * This method updates the passed-in reference with the value on the
   * top of the queue - if it can. If so, it'll return the value and
   * 'true', but if it can't, as in the queue is empty, then the method
   * will return 'false' and the value will be untouched.
   */
  virtual bool pop( T & anElem ) = 0;
  /**
   * This form of the pop() method will throw a std::exception
   * if there is nothing to pop, but otherwise, will return the
   * the first element on the queue. This is a slightly different
   * form that fits a different use-case, and so it's a handy
   * thing to have around at times.
   */
  virtual T pop() = 0;
  /**
   * If there is an item on the queue, this method will return a look
   * at that item without updating the queue. The return value will be
   * 'true' if there is something, but 'false' if the queue is empty.
   */
  virtual bool peek( T & anElem ) = 0;
  /**
   * This form of the peek() method is very much like the non-argument
   * version of the pop() method. If there is something on the top of
   * the queue, this method will return a COPY of it. If not, it will
   * throw a std::exception, that needs to be caught.
   */
  virtual T peek() = 0;
  /**
   * This method will clear out the contents of the queue so if
   * you're storing pointers, then you need to be careful as this
   * could leak.
   */
  virtual void clear() = 0;
  /**
   * This method will return 'true' if there are no items in the
   * queue. Simple.
   */
  virtual bool empty() = 0;
  /**
   * This method will return the total number of items in the
   * queue. Since it's possible that multiple threads are adding
   * to this queue at any one point in time, it's really at BEST
   * a snapshot of the size, and is only completely accurate
   * when the queue is stable.
   */
  virtual size_t size() const = 0;

Then it was easy to use these methods in place of the actual methods in the subclasses. It's just a better way to define the API. With that done, I was able to make the Hammer and Drain because when I needed to reference a Queue, I just used dkit::FIFO and that was good enough. Pretty nice.

Handling the Logging

One of the problems with multi-threaded testing is that the output tends to garble itself pretty totally at times, and it makes it near impossible to determine what was really meant by the output of the code. For example, I had the following in the Drain:

  std::cout << "[Drain::doIt(" << mID << ")] - popped "
            << mCount << " items off the queue" << std::endl;

but because it was dealt with as six different components, there was more than adequate time to have another thread jump into the output stream and have its output intermingle with the message I was trying to send.

So what's a better way? Well… have all the components in one place, like this:

  std::ostringstream msg;
  msg << "[Drain::doIt(" << mID << ")] - popped "
      << mCount << " items off the queue";
  std::cout << msg.str() << std::endl;

What I realized was that this still looks like two items, and the newlines were getting intercepted and causing the output to look bad. The final result I went with was the "all-in-one" idea:

  std::ostringstream msg;
  msg << "[Drain::doIt(" << mID << ")] - popped "
      << mCount << " items off the queue" << std::endl;
  std::cout << msg.str();

At this point, things looked a lot better, and I wasn't getting the scrambled messages. Now this is only good if the console writer is atomic, but it's a lot better bet doing it this way than hoping that the entire streaming operation was going to be atomic. That's just not happening.

Adding a Little Polish

Once I had the LinkedFIFO tests done, and the classes all ready to go, I checked it all in and then updated the docs to reflect the addition of the base class as well as the new dependency on boost and the rationale for it. I'm not sure that many are going to care - it's pretty isolated, if you really don't want to use boost - even though it's on even platform you could imagine, so it's not hard to remove. But it makes life and portability much easier.

It's been a productive morning. I need to go back and put the tests in for the CircularFIFO implementations, but that's not going to be too hard - after all, the same code will work on them that did on the LinkedFIFOs. I just need to move it over and let it run.

Apple Released Mac OS X 10.7.4 on Software Updates

Wednesday, May 9th, 2012

Software Update

Just saw on Twitter that 10.7.4 was released and includes a few bug fixes that even effect Acorn, my favorite image editing application. I'm not sure now much it'll effect me, as I'm not loading Photoshop images with more than 200 layers, but it's nice to see that it's getting fixed, and all these fixes will be going into 10.8 Mountain Lion this Summer.

I'm glad that it's all coming together today - a few updates, a building of boost, and then I'm starting to feel like the day hasn't been a waste.

Building Boost 1.49.0 on Mac OS X 10.7

Wednesday, May 9th, 2012

Boost C++ Libraries

I wanted to add in threading to DKit, but in order to do that I needed a threading model, and I had no desire to use straight pthreads, nor to include all I needed to encapsulate pthreads into a decent threading library. So I decided to give boost on OS X a try. I didn't want to use the Homebrew stuff as it's an entire package maintenance system, and I didn't want to even go near MacPorts. So I decided to do a simple boost install myself.

Turns out, it's exceptionally easy.

First, simply get the latest package from the Boost web site. Then put it in a directory - any directory, and then run the following:

  $ cd path/to/boost
  $ ./bootstrap.sh
  … some config output …
  $ sudo ./b2 architecture=x86 address-model=32_64 install

And what you'll get is everything built as 32- and 64-bit universal binary libraries and deposited in /usr/local/include/boost and /usr/local/lib. It's all there, and it's trivial to uninstall:

  $ cd /usr/local/include
  $ sudo rm -rf boost
  $ cd /usr/local/lib
  $ sudo rm -rf libboost_*

What could be more simple?

At this point, you can write simple little apps that use boost:

  #include <string>
  #include <boost/unordered_map.hpp>
 
  int main(int argc, char *argv[]) {
    boost::unordered_map<int, std::string>   a;
    a[4] = "yoyo";
    return 0;
  }

and then simply compile them without any unusual flags:

  $ g++ boost.cpp

Because it's all in /usr/local/include and /usr/lib - GCC automatically finds them. Sweet!

Now I can get to adding those threading ideas to DKit.

[5/23] UPDATE: if you plan to do any debugging, you need to make sure that the built shared, debug, versions of the libraries are available to you. This is easily done with the following after you build:

  $ cd path/to/boost
  $ sudo chown -R your_login:staff bin.v2

When the build is done as 'sudo', the directories created are all owned by root. You just need to revert them to you, and then gdb works wonderfully.

Google Chrome dev 20.0.1130.1 is Out

Wednesday, May 9th, 2012

Google Chrome

I just noticed that the Google Chrome team has released a new dev version: 20.0.1130.1, and the release notes say that it's focusing on a new version of the V8 javascript engine (3.10.8.4), and a raft of stability fixes. Glad that they are still working on things, but it's been a while since I've seen a really new feature or capability released that even remotely impacts me. Still… it's to be expected, really. The browser has become stable. There's HTML5, and it's widely supported in WebKit, and that's in Chrome, Safari, and many others. It's just not that dynamic a platform any more. And that is good news. Stable platforms are nice to write for.

Google Chrome dev 20.0.1123.1 is Out

Wednesday, May 2nd, 2012

Just noticed that the Google Chrome team has updated the dev pipeline to 20.0.1123.1 which is supposed to include the V8 javascript engine 3.10.6.0 as well as a few low-level mouse over fixes and a few Windows-specific updates. Nice to see, but it's really running amazingly well these days, so I can't imagine what they will be doing next.

Google Chrome dev 20.0.1115.1 is Out

Wednesday, April 25th, 2012

Google Chrome

This morning I noticed a somewhat minor update to Google Chrome dev to 20.0.1115.1. The release notes only say that there are "fixes" and an update for the V8 javascript engine to 3.10.5.0. Still, it's nice to see that it's making progress still as I'm thinking about a web project to keep me occupied while I'm off. I still need to finish the iOS/OS X library I'm working on, but after that, possibly a little more web stuff? Who knows.

Upgraded to Latest (March 2012) gfortran (4.7.0)

Wednesday, April 11th, 2012

fortran.jpg

I was reading a little from the newsgroups today and decided to have a look at the latest from the HPC on Mac OS X to see if they had an updated gfortran for OS X 10.7 - and indeed they did. I downloaded the package, updated my removal script and then installed the latest version. I then rebuilt my thesis code with it, and was happy to see that it all still worked.

Not that I didn't think it would, but it's nice that it still works.

I'm not sure what I was planning, but I have to admit that it might be really nice to get back into FORTRAN and just write code. But that's the same with C++, isn't it? I just want to write code. Not really mess with GUIs… not mess with people, and politics, and all the cruft that comes from dealing with people -- I just want to write code again.

Maybe I'll dig into my thesis and try to see where the convergence issues really are. I know they are there, but I'm not sure that FORTRAN is the best language to find them. Maybe Obj-C might be nice. It's certainly got all the functionality I'd need, and it'd be nice to be able to have the physics in modules, but we'll have to think about it a bit.

Google Chrome dev 20.0.1096.1 is Out

Wednesday, April 11th, 2012

This morning I noticed a minor milestone for Google Chrome dev - the 20.x.x.x series is out with 20.0.1096.1. There is a new V8 javascript engine, and a few more nice things in the release notes, but it's interesting that since I've been looking, I haven't done a lot of writing, and noes Chrome 20 is out. Kinda wild.