Monday, July 25, 2011

C++ 0x on Mac

Introduction
I was trying to convert my MSVC project into Qt Project so that it may compiled both on Windows and on Mac. But the problem is I used some of C++ 0x features in the project such as auto keyword, r-value reference and move constructor. Because my Qt on Windows uses MSVC 2010 compiler, there was no problem compiling it but the problem was on Mac which doesn't have C++ 0x feature yet.

What is special on Mac?
gcc 4.4 or later versions support C++ 0x standard but the version of gcc included in XCode 4.0 is still 4.2. Because I didn't have an excellent Mac specific knowledge, was thinking that it would be very easy to upgrade gcc into 4.4 or higher so that I may use C++ 0x standard on Mac. But it was not! The gcc compiler provided with XCode is not a normal gcc compiler but a special version which has been modified by Apple. Here I introduce how to use C++ 0x features with Qt Creator. May be I can try it also on XCode but I gave up because got a very dangerous feeling about switching XCode's default compiler.

Installation of gcc4.5
First, I installed gcc4.5 on my Mac by using of fink command 'fink install gcc45'. The command is very simple but the installation process took about 5 hours! Please note that if you are about to install a new version of gcc compiler via fink command on Friday afternoon and you got an date that night, you should give up one of beween date and gcc installation.

Qt Configuration
Now, launch your Qt Creator to modify the setting so that you may use gcc 4.5 compiler on your Qt Creator.
1. add gcc 4.5 into Tool Chains

Open preference window then choose Tool Chains on the tab on the left side of the preference window.
Click "add" button and choose "GCC" on the popup menu. Rename it into a new name such as "GCC4.5" to avoid confusing between other GCC compilers by double clicking the name.
Then set the compiler path , debugger, and ABI values. The gcc4.5 binary is usually located in /sw/bin/ and  its name is g++-4 or G++-4.5.
2. Create qmakespec for gcc4.x
There are differences between Apple's gcc compiler and gnu version of gcc compiler. Among these differences, in this time, -arch and -Xarch flag are the things to be cared. Qt's qmake predefined specification data is using -arch and Xarch flag to specify architecture values such as intel 32bit, intel 64bit, PPC 32bit, and PPC 64bit. We should make it work with our gcc compiler by switching these flags into -m32 or -m64.
Here is an example.
Go to your mkspecs directory of Qt. You can find out the location by checking Qt4 tab on Preferences.

Then make a copy of macx-g++ with a new name such as macx-gnu-g++. When you open qmake.conf file, you can see a line like below at the end of file.
include(../common/mac-g++.conf)
Most of environment values for qmakeconfig are stored in the file, ../common/mac-g++.conf. Let's change it into a new file name such as ../common/mac-gnu-g++.conf.
Go to common directory then copy mac-g++.conf file with a new name mac-gnu-g++.conf.

QMAKE_CFLAGS_X86_64     += -m64 -mmacosx-version-min=10.5
QMAKE_OBJECTIVE_CFLAGS_X86_64  += -m64 -mmacosx-version-min=10.5
....
QMAKE_CXXFLAGS_X86_64   += -m64  -mmacosx-version-min=10.5
QMAKE_CXXFLAGS_X86      += -m32

QMAKE_CC         = gcc-4
QMAKE_CXX        = g++-4

3. Modify Build Setting
Now, almost done! Select "Projects" tab on left side of the Qt Creator, then you will see "Build Settings". Go to the second section, "Build Steps" then put the value "-spec mac-gnu-g++" into "Additional Arguments".

Finished!
In my case, I can compile most of Qt projects by doing above things. But depending on the projects, especially depended libraries, there could be some more things to do.
Thank you.

Sunday, July 24, 2011

Why we are making software?

About six years ago, my company launched a video chat software which had excellent performance but was not so popular at the beginning. Just right after releasing the first version, I was visiting the users feedback pages every day and identifying what kind of problem my software had. Most of the feedbacks were dissatisfactions because most of users had never used video chatting software before and didn't know how to use their web cams and adjust their microphones. One day, I found an unusual title, "Thank you." I opened the post with curious and thrill. The author of the poster was a handicap in his eyes. His vision was very poor and should approach his head to the monitor within 2 or 3 inches space to read the text on the screen. According to the posting, he has a very young son who lives very far from him because of his work. He wanted to see his son but it was very difficult. When the video chat software was released, he decided to use it to see the face of his son. Even though he needed to stick his head into the monitor to see his son, he was very happy whenever he saw his son. So he decided to leave a message on the feedback board that he was using this software very usefully and if the video window is bigger, he will be happier because he can see the face of his son more clearly. While reading the post, I was very impressed and reconsidered the meaning of what I'm doing.


After then, I decided that I should put the full-screen video chat function into the program and suggested it to my UX and planning team. They agreed about the requirement and I volunteered to make the function. When the full screen function was released, I notified him about it and he sent me a thank you mail. 
It was one of my impressive things among my entire software development life.


We are developing softwares and it is sometimes very successful but sometimes it is not. But beyond the success of our projects, we should know that we are making software to help our neighbors. 

Friday, July 22, 2011

C++ books

Introduction
There are many C++ related books in bookstores but it is not so easy to find a book for mid-senior C++ programmers. Usual C++ books are for the beginners and with the title like "Complete C++ in 45 days". I am interviewing many candidates for C++ development engineer positions at my company who, of course, mentioned C++ on their resumes. But most of them are not really good at C++ programming and cannot explain how virtual destructor works, why we should worry about "self assignment", differences of const keywords by their positions.
I introduce some good C++ books here and I have no relationship with these authors. (But I'm translating some parts of C++ FAQ web version into Korean)

Effective C++, More Effective C++, and Effective STL
Effective Series are very famous books for who are want to know more about C++ and how to use it more effectively. I use to read these effective books these days even though I used C++ more than 10 years now.









C++ FAQs


Even though Effective C++ series are very good books but these books are not covering entire thins. You can find more about C++ that you are usually curious while using C++ such as pointers to member functions, why it is not safe to delete the same pointer twice, and etc.
There are two versions of C++ FAQs. One is named C++ FAQs lite and you can read it via web site at http://www.parashift.com/c++-faq-lite/ for free. and the other is book version of C++ FAQ. You can find out the differences between these two version at http://www.parashift.com/c++-faq-lite/faq-book.html.

An Implementation of inter-thread communication between UI thread and Worker threads with WTL

Introduction
The basic concept of this implementation is explained on my previous post.



Implementation
Class Diagram



Event Object
class WtlEventConnector:public CWindowImpl
{
public:
 static WtlEventConnector& GetInstance()
 {
     static WtlEventConnector instance;
  return instance;
 }

 void Initialize()
 {
  if (m_hWnd)
        {
   return;
        }

  HWND hWnd = Create(GetDesktopWindow(), 0, 0, WS_POPUPWINDOW);
  if (!hWnd)
  {
   throw std::runtime_error("WtlEventHandler Window Creation failed");
  }
 }

 bool FireEvent(int nValue, BaseEventHandler* pHandler)
 {
  if (!m_hWnd)
  {
   return false;
  }
  PostMessage(WM_FIRE, nValue, reinterpret_cast(pHandler));
  return true;
 }

 BEGIN_MSG_MAP ( WtlEventHandler )
 MESSAGE_HANDLER ( WM_FIRE, OnFire )
 END_MSG_MAP()

protected:

 LRESULT OnFire(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL bHandled)
 {
  WtlEventTrigger* pHandler;
  pHandler = reinterpret_cast(lParam);
  pHandler->onMainThread(wParam);
  bHandled = TRUE;
  return 0L;
 }

private:
 WtlEventConnector()
 {
 }

 ~WtlEventConnector()
 {
  if (m_hWnd)
  {
   DestroyWindow();
  }
 }
};


WtlEventTrigger::WtlEventTrigger()
{
 CPortalNetThreadChangerWTL::GetInstance().Initialize();
}

void WtlEventTrigger::fire(int value) // NS

{
 WtlEventConnector::GetInstance().FireEvent(value, handler);
}

Saturday, July 16, 2011

An Implementation of inter-thread communication between UI thread and Worker threads with Qt

Introduction
The basic concept of this implementation is explained on my previous post.

Architecture

Implementation

Event Object
class QtITCEvent:public QEvent
{
public:
    QtITCEvent(BaseEventHandler& handler, int val)
        :QEvent(IPC_THREAD_EVENT),
        value(val),
        handler(receiver)
    {

    }
    int getValue() // NS
    {
        return value;
    }

    CPortalNetThreadChanger& getHandler() // NS
    {
        return handler;
    }

private:
    int value;
    BaseEventHandler& handler;
};

class QtEventHandler:public QObject, BaseEventHandler
{
public:
    static BaseEventHandler& getInstance() // NS
    {
        static QtEventHandler instance;
        return &instance;
    }

protected:
    virtual bool event ( QEvent * e ) // NS
    {
        if (e->type() == IPC_THREAD_EVENT)
        {
            QtITCEvent* myEvent = dynamic_cast(e);
            if (!myEvent)
            {
                return false;
            }
            myEvent->getHandler().onHandleEvent(myEvent->getValue());
            return true;
        }
        return false;

    }
private:
    QtEventHandler()
    {

    }
    QtEventHandler(QtEventHandler&);
    void operator=(QtEventHandler&);


};

QtEventTrigger::QtEventTrigger()
{
    if (IPC_THREAD_EVENT == QEvent::None)
    {
        IPC_THREAD_EVENT = static_cast(QEvent::registerEventType());
    }
}

QtEventTrigger::~QtEventTrigger()
{

}

void QtEventTrigger::fire(int value) // NS
{
    QtITCEvent * event = new QtITCEvent(this, value);
    QCoreApplication::postEvent(QtEventHandler::getInstance(), event);
}

Tuesday, July 12, 2011

Performance Enhancement with Core Technologies

Introduction
When I was a 10 year old boy, I made a shooting game running on Z-80a processor. It was mostly written in BASIC and little bit in Assembly. I designed all the game scenario, bitmaps pixels for the game characters displayed on the graphic unit, V9938D and sound effects played through the PSG sound device. It was my first programming.

As I remember, the the Z-80a processor had a clock rate 4.77 MHz. Since then the processor speed had incredibly upgraded. In 2002, an Intel Pentium 4 model was introduced as the first CPU with a clock rate of 3 GHz. But recently it seems that the clock rate almost reached to its limit because it is hard to see any CPU faster then 3.5 GHz today even though the highest clock speed microprocessor ever sold commercially to date is found inside IBM's zEnterprise 196 mainframe, introduced in July, 2010. The z196's cores run continuously at 5.2 GHz.

To avoid the limit of the clock rate, CPU manufactories are approaching to SIMD and multi-core technologies and now we even have dual core smart phones.


SIMD extension

Single instruction, multiple data (SIMD), is a class of parallel computers in Flynn's taxonomy. It describes computers with multiple processing elements that perform the same operation on multiple data simultaneously. Thus, such machines exploit data level parallelism. from WikiPedia
Flynn's Taxonomy of a SImD design: single instruction, multiple data. Each "PU" (processing unit) does not necessarily correspond to a processor, just some functional unit that can perform processing. The PU's are indicated as such to show relationship between instructions, data, and the processing of the data.
SIMD extension is a very useful technology when it is applied to multimedia processing. I have done some of multimedia related software development and have experienced the advantage of SIMD extension. You can see an example of my SIMD extension related work here.


Parallel Processing
As I mentioned above, The clock rate has reached almost its limit thus microprocessor manufactures are finding their solution in multi-core technology.
OpenMP is one of famous parallel processing library and Microsoft recently introduced parallel pattens library in Visual Studio 2010. I introduce these two libraries here.

OpenMP
The OpenMP Application Program Interface (API) supports multi-platform shared-memory parallel programming in C/C++ and Fortran on all architectures, including Unix platforms and Windows NT platforms. Jointly defined by a group of major computer hardware and software vendors, OpenMP is a portable, scalable model that gives shared-memory parallel programmers a simple and flexible interface for developing parallel applications for platforms ranging from the desktop to the supercomputer.

int main(int argc, char *argv[])
 {
   #pragma omp parallel  
   printf("Hello, world.\n");
   return 0;
 }

You can see more detail about OpenMP and download it at http://openmp.org/

Microsoft Parallel Patterns Library
The PPL introduces a set of task-oriented parallelism constructs as well as a number of parallel algorithms similar to what is available with OpenMP today. The PPL algorithms are, however, written using C++ templates rather than pragma directives and, as a result, are far more expressive and flexible. The PPL is, however, fundamentally different from OpenMP in the sense that the PPL promotes a set of primitives and algorithms that are more compassable and reusable as a set of patterns. Meanwhile, OpenMP is inherently more declarative and explicit in matters such as scheduling and ultimately is not part of C++ proper. The PPL is also built on top of the Concurrency Runtime, allowing for greater potential interoperability with other libraries based on the same runtime. Let's look at the PPL algorithms and then see how you can use the underlying functionality directly for task-oriented parallelism.


 - writing in progress.... to be finished soon...

Sunday, July 10, 2011

Cross-platform C++ libraries

Introduction
There are some cross-platform C++ libraries and some of them contain UI Frameworks.
I introduce these libraries and my experiences of them here.

Cross-platform C++ libraries with UI Frameworks
There are two cross-platform C++ libraries which have UI Frameworks as I know. Both of these two libraries are implemented based on adapter pattern.

Qt by Nokia
Qt (pronounced officially as cute /ˈkjuːt/, though often incorrectly as Q.T. /ˈkjuːˈtiː/) is a cross-platform application framework that is widely used for developing application software with a graphical user interface (GUI) (in which cases Qt is classified as a widget toolkit), and also used for developing non-GUI programs such as command-line tools and consoles for servers. Qt is most notably used in Autodesk Maya, Google Earth, KDE, Adobe Photoshop Elements, OPIE, Skype, VLC media player, VirtualBox, and Mathematica, and by the European Space Agency, Siemens, Volvo, Walt Disney Animation Studios, Samsung, Philips, and Panasonic. - from Wikipedia

Qt SDK combines the Qt framework with tools designed to streamline the creation of applications for Symbian and Maemo, MeeGo (Nokia N9) in addition to desktop platforms, such as Microsoft Windows, Mac OS X, and Linux.

I want to mention two most impressed things while I've been using Qt: One is well-designed architecture for cross-platform UI framework, the other is Qt Creator, powerful cross-platform integrated development environment, including UI designer tools and on-device debugging. I really like Qt Creator and recommend it even though it crashes sometimes :). If you are sick of slow response of MSVS or XCode, I'd like to advice you to have a chance of using Qt Creator. It really responses very quick and is easy to add source code files to project and to modify project setting. Qt Creator use gcc compiler by default with Mac and Linux, and MinGW with Windows but you can change it into MSVC compiler or Intel compiler.

Qt is available under GPL v3, LGPL v2 and a commercial license. Learn more about licenses here.

wxWidgets
wxWidgets (formerly wxWindows) is a widget toolkit for creating graphical user interfaces (GUIs) for cross-platform applications. wxWidgets enables a program's GUI code to compile and run on several computer platforms with minimal or no code changes. It covers systems such as Microsoft Windows, Mac OS X (Carbon and Cocoa), iOS (Cocoa Touch), Linux/Unix (X11, Motif, and GTK+), OpenVMS, OS/2 and AmigaOS. A version for embedded systems is under development.  - from Wikipedia

wxWidgets provides MFC like classes, thus it is a good option for C++ developers who are familier to MFC or WTL. But there are few things to know attentively. UI classes in wxWidgets are usually using self destruction when their windows are destroyed. If you use these UIs without having enough understanding of their self destruction mechanisms, it will bring serious problems such as abnormal termination by double deletion of the object. wxWidgets is still under development and upgrading. It's getting better as it's version is upgraded, but I am still experiencing some problems with Mac OS X such as unimplemented APIs or odd behaviors.

Cross-platform C++ libraries without UI classes
There are several cross-platform C++ libraries without UI functions and these libraries are widely used to develop server side applications. Usually these libraries are liter than GUI libraries.


POCO
The POCO C++ Libraries are a collection of open source class libraries for developing network-centric, portable applications in C++. POCO stands for POrtable COmponents. The libraries cover functionality such as threads, thread synchronization, file system access, streams, shared libraries and class loading, sockets and network protocols (HTTP, FTP, SMTP, etc.), and include an HTTP server, as well as an XML parser with SAX2 and DOM interfaces and SQL database access. The modular and efficient design and implementation makes the POCO C++ Libraries well suited for embedded development. - from Wikipedia


I applied POCO to my latest project and am very satisfying with it. The design of classes shows good hierarchy and it is well understandable. I could use its functionality without spending much time to read the document and all of my codes have been working correctly without fixing or modification. I can say that POCO is a very stabilized library just like STL, and a nice solution for cross-platform development. I want to thank POCO developers for making this nice open source library.

BOOST
The Boost C++ Libraries are a collection of free libraries that extend the functionality of C++.

Things to consider to implement cross-platform enduser applications

Introduction
When we look back just a few years ago, Microsoft windows had shared over 90% of PC Operating System market and most of desktop enduser application developers had considered only this Windows environment. But these days, Mac OS X market share up 29%. Thus it's time to consider our desktop software supporting not only windows but also Mac OS X.

What we should consider
There are several differences between Windows and Mac OS X such as file path representation, case sensitivity for file names and directory names, storing method for configurations of applications, user access policies for system resources, socket APIs, and etc. Most of all, the hardest things to support cross-platform with Windows and Mac OS X are the differences of GUI APIs and abstract implementation of the UI event loop. There are several UI controls in both operating systems and some of them are similar but some controls exist only in Windows or only implemented in Mac. Event hough some UI controls look similar to both sides but APIs to create and to manage these are very different.


Things to consider for cross-platform development for enduser applications

UI controls for windows are created and managed by WIN32 APIs. WIN32 APIs are C based API which use 'handle's called HWND to create and manage UI controls. Carbon or COCOA is used on Mac OS X environment. Carbon is the C based old API and COCOA is the Objective-C based API to manage UI controls.

APIs for several Operating Systems
Our Goal
There are several ways to implement cross-platform enduser applications. But if possible, make it into one source code and not to be modified many things to compile with other operating systems so that we may reduce development and maintenance costs.
Goal to cross-platform enduser application development
I would like to share my experiences of implementation of some of commercial cross-platform enduser application development here to help C++ software developers who are looking for ways to easily develop enduser application for both Windows and Mac.

Inter-thread communication methods between UI thread and worker threads - 2

Inter-thread communication methods for each framework


Here I introduce inter-thread communication method for three most popular UI frameworks

Windows (WTL, MFC) 
  • Use WIN32 API PostMessage
  • PostMessage(HWND hwnd, UINT id, WPARAM, LPARAM)
Unfortunately, WIN32 is not C++ API but  old C based API therefore when we pass an event object through the WIN32 API PostMessage(), the event object should be reinterpret casted into LPARAM or WPARAM and the receiver also use unsafe typecast to convert from LPARAM or WPARAM into the event object. Additionally the destination, which receives PostMessage event, should have a window handle, HWND or use PostThreadMessage() so that the run-loop may handle the message by itself.

Qt
  • Qt has its own runloop and event object
  • void QCoreApplication::postEvent ( QObject * receiver, QEvent * event, int priority )
Qt provides a very nice object based event posting method. We can use QEvent class to pass information to the UI thread. if the basic information container that QEvent class provides is not enough to hold the information that you want to post, you can subclass the QEvent class then add methods or member variables which can contain the information you want to send to UI thread.
    COCOA
    • Use performSelector method 
    • - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait
    NSObject, the root class of COCOA, provides a fancy method, performSelectorOnMainThread which can assign the destination object and method, and pass any type of class.

    Unified channel for notifications from worker threads to UI thread

    All above communication methods have simular behaviors, first the notification messages are stored into one serialized queue, usually called 'message queue', (of course this process is thread safe and considered mutual exclusions among threads) and the main run loop pops the event from the queue and deliver it to the destination. Because the priority jobs of the UI thread is updating UI and processing messages from kernel layer, events from our worker threads could be delayed and it's up to the policy of the run-loop and this policy makes its UIs look move faster.
    Because all the requests from worker threads are stored in a single message queue, it is good idea that unify the channel from worker threads to UI threads. If we make several types of events for inter-thread communication, the main run-loop should have branch conditions as many as the count of event types.
    The ideal goal is to make the worker thread's runnable base class have its notification procedure to UI thread.

    Class Diagram: Event handler for UI thread to handle events from worker thread

    Class Diagram: EventTrigger for worker threads



    Implementation for each framework
    • Implementation with Objective-C performSelector method on COCOA Framework
    #import "PotalNetThreadChanger.h"
    
    #import 
    #include 
    
    @interface PotalNetThreadChanger : NSObject {
    @private
        CPortalNetThreadChanger* changer;
    }
    - (void)toMainThreadByChanger:(CPortalNetThreadChanger*) pChanger withIntValue:(int) intValue;
    + (PotalNetThreadChanger*)default;
    @end
    
    
    @implementation PotalNetThreadChanger
    
    - (id)init
    {
        self = [super init];
        if (self) {
            // Initialization code here.
        }
        
        return self;
    }
    
    - (void)dealloc
    {
        [super dealloc];
        NSLog(@"Objective-C class PotalNetThreadChanger destructed succssfully");
    }
    
    - (void) onMainThreadToChanger:(CPortalNetThreadChanger*)pChanger withIntValue:(int)intValue
    {
        pChanger->onMainThread(intValue);
    }
    
    - (void)onMainThreadWithId:(NSString*)stringValue;
    {
        int intValue = [stringValue intValue];
        [self onMainThreadToChanger:changer withIntValue:intValue];    
    }
    
    - (void)toMainThreadByChanger:(CPortalNetThreadChanger*) pChanger withIntValue:(int) intValue
    {    
        if (![NSThread isMainThread])
        {
            @synchronized(self){
                changer = pChanger;
                // do not use NSString::stringWithFormat method because this thread doesn't have auto release pool!
                NSString* stringValue = [[NSString alloc]initWithFormat:@"%d", intValue];
                [self performSelectorOnMainThread:@selector(onMainThreadWithId:) withObject:stringValue waitUntilDone:YES];
                [stringValue release];
            }
            return;
        }
        [self onMainThreadToChanger:pChanger withIntValue:intValue];
    }
    
    + (PotalNetThreadChanger*)default
    {
        static PotalNetThreadChanger* defaultChanger = [[PotalNetThreadChanger alloc]init];
        return defaultChanger;
    }
    @end
    
    CPortalNetThreadChanger::CPortalNetThreadChanger()
    {
        
    }
    CPortalNetThreadChanger::~CPortalNetThreadChanger()
    {
        std::clog << "class CPortalNetThreadChanger destructed successfully" << std::endl;
        [[PotalNetThreadChanger default]release];
    }
    void CPortalNetThreadChanger::toMainThread(int value)
    {
        [[PotalNetThreadChanger default]toMainThreadByChanger:this withIntValue: value];
    }
    
    

    Monday, July 4, 2011

    Inter-thread communication methods between UI thread and worker threads - 1

    Introduction

    There are lots of requirements of Smart phone application developers these day. And one of key technology for the beginner level of smart phone developer is  how can he make UI faster. It's because usually CPUs of smart phones are slower than Desktops, if we write code that does not only UI update but also every other things such as managing database or network connectivity, the UI responses very slow. In order to avoid this problem, we should make worker threads that do everything except UI updates so that the main thread may focus on only UI update jobs.

    Inter-thread communication between UI thread and worker threads


    Most of UI application programmers know that UI updates should be done in one thread(usually the main thread and some people call it UI thread) and create child threads doing other works. One of most important things in separate UI thread and worker thread is the communication method between threads. Because we usually create our worker threads with our own run loop, we easily take care of mutual exclusions among threads and easily communicate among them by using of our own task queue or pipe or any other lots of ways. But we usually don't make the run loop of the main thread (UI thread), we should use the inter-thread communication methods that the UI framework provides and to use these methods, we should know how to deal it and what to be concerned.

    Implementation of "result of the task" signal has system dependency because the run-loop of UI thread is usually provided by UI framework

    Sunday, July 3, 2011

    Who Am I?

    I am a principle software engineer and development lead at NHN Corporation.

    I have been leading several C++ based desktop application development project and some of iPhone software development.

    I am interested in performance improvement by using of SIMD extension and parallel processing, and cross-platform C++ programming can cover UI layers with Windows and MAC OSX(of course, make sure to be compiled on Linux machine too :) ).

    This blog is dealing with C++ 0x, STL, Objective-C / COCOA, AVE(Advanced Vector Extension) and some of cross-platform libraries such as POCO, Qt, wxWidgets and BOOST.

    Thankyou