Tuesday, April 10, 2007

Time is everything.

A simple one for you today, but useful none the less.

It involves time. Whether or not it is the fire in which we burn is up for grabs, but you still might want your libc program to be able to output the time!

In a program I wrote this week I did it this way:

#include <time.h>

char* mtime()
{
    static char return[16];
    time_t rawtime;
    struct tm * t;
    time( &rawtime );
    t=localtime( &rawtime );
    snprintf(return,16,"[%02d:%02d%02d]",t->tm_hr,t->tm_min,t->tm_sec);
}

This function returns a string in the format [hr:mn:sc] (hour:minute:second). It will always print two characters for each field, if none are provided it will print zeroes (this is useful as time returns 1 second as 1 not 01, so if you want the string to always be the same length you have to pad it with zeroes).

Time fills the time_t variable called rawtime with the current time since 1970 in seconds. To get something useful to humans we use another function on that returned time. In this case since we want the local time (which also includes the timezone calculation for us) then we call rawtime, which returns a struct* to a tm. I assume it is statically allocated within the localtime function. It may be wise to copy the data out of the struct if you intend to use it much later in your code, but since I use it on the next line, and I haven’t had any problems with it, my code will stay like that until there is a problem :).

Enjoy,

-Crusher4

Monday, April 2, 2007

pthread attributes.

I meant to post more last week, but we had a huge LAN party at WSU a few days ago, thanks to everyone who came and made it awesome :).

Anywho...My next tidbit of information is about pthreads. I had to learn this because when I was writing a piece of software for work, I noticed that I couldn't launch more than about 300 threads before it would start refusing to launch more. After a few hours of research on google I found that it was due to the fact that even though each thread was only using kilobytes of memory, the default thread stack size is somewhere in the range of 1-8mb in most linuxes (it was 8 in the os I was using), which means that even though there was only about 4mb allocated in my program the system was "out of memory" to allocate. But thats ok, we can fix it, we have the technology.

This can all be remedied by changing the thread stack size before we create new pthreads. It is accomplished with this simple bit of code:

size_t size = 0x10000;
pthread_attr_t tattr;

if (pthread_attr_init(&tattr) !=0 )
{fprintf(stderr,"pthread_attr_init() failed\n");}
if (pthread_attr_setstacksize(&tattr,size) !=0 )
{fprintf(stderr,"pthread_attr_stacksize() failed\n");}

pthread_attr_getstacksize(&tattr,&size); /* find out the stacksize */
fprintf(stderr,"Thread stack size: %dKB\n",(int)size/1024);

The last two lines are not needed, but I like to keep them in especially while I am developing this software, to make sure it is working the same way on various computers I try compiling it for. Using that value of size it will have threads with 64KB of stack size.

You can check the defaults of your linux for stack size, open file discriptors, and all the other things you need to make sure of when writing an intensive network app by typing 'ulimit -a'.

But more ulimit things later.

Over and out.

-Crusher4