sourcecode

Wednesday, June 26, 2013

const volatile

http://www.daniweb.com/software-development/c/threads/187964/const-volatile

When const volatile are used together:

const means the program can not modify the value volatile means the value may be arbitrarily modified outside the program.
the two are separate and not mutually exclusive.
use them together, for instance, in the case of reading a hardware status register. const prevents the value from being stomped on, while volatile tells the compiler that this value can be changed at any time external to the program.
this const volatile will thus satisfy both requirements and prevent an optimizing compiler from incorrectly optimizing the code, that it would do if only "const" were used.


Let's take an example
const volatile usigned int *REG_A = (usigned int *) init_hardware_n_return_address of REG_A();
In the above snippet function "init_hardware_n_return_address of REG_A()" modifies the content of the REG_A( register A say) of a peripheral device , say after initiatialising it ( which cause the content of R/W register REG_A modified by peripheral itself) and returns the address of REG_A to the program .

The assignment in the above snippet implies here that content of REG_A can be modifiable only be external sources like peripheral hardware itself and and your code is not supposed to modify the content of REG_A .
Also whenever such variable is encountered compiler should "load " it value every time instead of doing any code optimasation
Typically memory mapped variables are one consumers for such usage

Declaring a variable as const indicates the compiler that the variable will never be changed(either by the program/external entity like a peripheral device.
Declaring a variable as volatile indicates the compiler that the variable might be changed dynamically (by an external entity or by our program). Hence whenever we are accessing that variable, compiler will not perform optimization and will fetch the value from its address(which will cost us a few more cpu cycles).
Now Declaring a variable as a const volatile, we indicate the compiler that variable cant be modified by the program but can be modified by an external entity.
The usage of const volatile is more predominant in Device Driver Programming.

Monday, June 10, 2013

tools

sudo apt-get install libxml2-dev
sudo apt-get install libcurl4-openssl-dev
sudo apt-get install libmysql++-dev
sudo apt-get install cimg-dev
sudo apt-cache search libjpeg-dev
sudo apt-get install libgearman-dev

clang bug chrono and thread

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53841

chrono thread bug fix for:
linux error: no matching constructor for initialization of 'duration' 

using the Suggested fix:

- const chrono::nanoseconds __delta = __atime - __c_entry;
- const __clock_t::time_point __s_atime = __s_entry
+ __delta; + const auto __delta = __atime - __c_entry;
+ const auto __s_atime = __s_entry
+ __delta; in file condition_variable 

@ line 110 in /usr/include/c++/4.7

After install something, link them to /usr/local/bin, /usr/local/include, /usr/local/share so that the system path can find them anywhere

Monday, May 6, 2013

Start valgrind

Profiler under linux64

1. Install
http://www.cprogramming.com/debugging/valgrind.html
Download from http://www.valgrind.org/downloads/valgrind-3.8.1.tar.bz2
Then
$ bzip2 -d valgrind-XYZ.tar.bz2
$ tar -xf valgrind-XYZ.tar
$ ./configure
$ make
$ make install 
Then need to install the glibc-debuginfo
$ sudo apt-get install valgrind

2. Write a C++ program
http://jblevins.org/log/valgrind
#include <stdlib.h>

  void f(void)
  {
     int* x = (int*)malloc(10 * sizeof(int));
     x[10] = 0;        // problem 1: heap block overrun
  }                    // problem 2: memory leak -- x not freed

  int main(void)
  {
     f();
     return 0;
  }


3. Compile it with -g debug flag on

4. run
$ valgrind ./a.out

Sunday, April 14, 2013

C/C++ with Gearman (as worker)

The document is very vague about how to register a function. It turned out that the prototype/signature of the function gearman_worker_fn is very import:
typedef void*( gearman_worker_fn)(gearman_job_st *job, void *context, size_t *result_size, gearman_return_t *ret_ptr)
And since all the online document links are broken, I had to create using Doxygen, under folder /usr/local/include/libgearman-1.0

#include <iostream>
#include <libgearman/gearman.h>
#include <cstring>

using namespace std;

 void* gworker_fn_demon(gearman_job_st *job, void *context, size_t *result_size, gearman_return_t *ret_ptr)
{
   auto jobptr = gearman_job_workload(job);//this takes the data from the client
   if (jobptr) std::cout << "job: " << (char*) jobptr << std::endl;
  *ret_ptr = GEARMAN_SUCCESS ;
  *result_size = 6;

  cout<<"job received"<<endl;
  //char* result = new char[100];//bug here: free/new mismatch reported from valgrind
char* result = (char*)malloc(100 * sizeof(char));
for(int ii = 0; ii < 4; ++ii){
  result[ii] = 'a' + ii;
 }
 result[4] = '\n';
 result[5] = '\0';
 return result;//the memory is freed at client side

 }


int main()
{
 auto status_print = [](gearman_return_t gserver_code){
   cout<<gserver_code<< " --  "; 
   if (gearman_success(gserver_code)) cout<<"success";
   if (gearman_failed(gserver_code)) cout<<"failed";
   if (gearman_continue(gserver_code)) cout<<"continue";
   cout<<endl;
 };

 gearman_worker_st* gworker = gearman_worker_create(NULL);
 

 
 const char* ghost = "127.0.0.1";
 in_port_t gport = 4730;

 gearman_return_t gs_code = gearman_worker_add_server(gworker, ghost, gport);

 status_print(gs_code);


 const char* function_name = "wwcc";
 unsigned timeout = 0;
 void * job_context = NULL;

 gs_code = gearman_worker_add_function(gworker,function_name, timeout, gworker_fn_demon, job_context);

 status_print(gs_code);



 gs_code = gearman_worker_work(gworker);

 status_print(gs_code);

 

 gearman_worker_free(gworker);


 cout<<"done"<<endl;
 return 0;
}

Python with Gearman (as worker)

http://pythonhosted.org/gearman/worker.html

#!/usr/bin/python
import gearman
import time
def check_request_status(job_request):
    if job_request.complete:
        print ("Job finished! ")
        print (job_request.result)
    elif job_request.timed_out:
        print ("Job timed out!")
    elif job_request.state == JOB_UNKNOWN:
        print ("Job connection failed!" )

gm_worker = gearman.GearmanWorker(['localhost:4730'])

def task_listener(gearman_worker, gearman_job):
    return gearman_job.data + ' from listener\n'

gm_worker.set_client_id('whatever iid');
gm_worker.register_task('wwcc', task_listener)

gm_worker.work()

Saturday, April 13, 2013

C/C++ with gearman (as client)

gearman library (libgearman) can be directly called in C/C++ programs. (gearmand --version 1.1.5)

http://gearman.info/libgearman/examples.html

And my makefile:

 a.out:callrev.cpp
           clang++ -o $@ $^ -std=c++11 -lgearman

Together with the worker command from last post, here is a complete C++ program as a client:


#include <libgearman/gearman.h>
#include <iostream>
#include <cstring>
using namespace std;

int main(){
 gearman_client_st* gclient = gearman_client_create(NULL);
 gearman_return_t gsc = gearman_client_add_server(gclient, "127.0.0.1",4730);

 auto status_print = [](gearman_return_t gserver_code){
  cout<<gserver_code<< " --  "; 
  if (gearman_success(gserver_code)) cout<<"success";
  if (gearman_failed(gserver_code)) cout<<"failed";
  if (gearman_continue(gserver_code)) cout<<"continue";
  cout<<endl;
 };

 status_print(gsc);

 const char* function_name = "wwcc";

 const char* unique = "whatever unique";
 const char* workload = "aa bb cc";
 size_t workload_size = strlen(workload);
 size_t result_size;
 gearman_return_t return_code;
 void* value = gearman_client_do(gclient, function_name, unique, workload, workload_size, &result_size, &return_code);

 status_print(return_code);
 const char* result = static_cast<char*>(value);
 cout<<result<<endl;


 free(value);
 gearman_client_free(gclient);
 
 return 0;
}