Search This Blog

Showing posts with label GCC. Show all posts
Showing posts with label GCC. Show all posts

Wednesday, September 30, 2009

Sleep-ing in pthread

Using any variant of sleep for pthreads, the behaviour is not guaranteed. All the threads can also sleep since the kernel is not aware of the different threads. Hence a solution is required which the pthread library can handle rather than the kernel.

A safer and cleaner solution to use is the pthread_cond_timedwait...


pthread_mutex_t fakeMutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t fakeCond = PTHREAD_COND_INITIALIZER;

void mywait(int timeInSec)
{
struct timespec timeToWait;
struct timeval now;
int rt;

gettimeofday(&now,NULL);

timeToWait.tv_sec = now.tv_sec + timeInSec;
timeToWait.tv_nsec = now.tv_usec*1000;

pthread_mutex_lock(&fakeMutex);
rt = pthread_cond_timedwait(&fakeCond, &fakeMutex, &timeToWait);
pthread_mutex_unlock(&fakeMutex);
printf("\nDone\n");
}

void* fun(void* arg)
{
printf("\nIn thread\n");
mywait(5);
}

int main()
{
pthread_t thread;
void *ret;

pthread_create(&thread, NULL, fun, NULL);
pthread_join(thread,&ret);
}

For pthread_cond_timedwait , you need to specify how much time to wait from current time.

Now by the use of the function mywait() only the thread calling it will sleep and not the other pthreads.

Note : I have not checked the return values of the functions for error. Please do the same.

Wednesday, September 9, 2009

__attribute__ keyword

The __attribute__ is used to assign an attribute to a function or data declarations.

Primary Purpose : Make it possible for the compiler to perform optimization.

a) Functions :
The keyword is assigned to a function in declaration of function prototype.

eg : void func() __attribute__((, ,...)) ;

void func()
{
.......
.......
}

b) Data declarations
Attributes can also be assigned to variables, and also to members of struct.


I have explained a few attributes which i found might be more of use, others are just mentioned. For detailed explanation, u can refer to the source mentioned at the end.
  • Attributes in Function Declaration:
(i) alias
Function becomes a weak alias of another function.

(ii) always_inline
Function will always be expanded as inline, even if no optimization is specified.

(iii) const
Function does not read/write global memory. Optimizer need not make certain that global values are updated before the function is called. Helps in exploiting parallelism.

(iv) constructor
Function will be called before main is called.

(v) deprecated
Gives warning on use.

(v1) destructor
Function will be called after main has returned or exit is called.

(vii) format

(viii) format_arg

(ix) malloc

(x) no_instrument_function

(xi) noinline
Function will never be expanded as inline code.

(xii) noreturn
Function will not return to its caller. Thus, the optimizer can neglect any code that would be normally executed on the functions return.

(xiii) pure
Function does not write to global memory. Allows optimizer to perform common subexpression optimization, since global data wont change in the function.

(xiv) section
The assembly code of the function is kept in the named section instead of the default text section.

Example :
Consider a C program try.c
void try(void) __attribute__((section("mysection")));

void try()
{
int a = 0;
a = a + 10;
}

int main()
{
printf("\nIn main\n");
return 0;
}

Compile it with -S option to get the equivalent assembly code for the program.
gcc -S try.c

A try.s file will be created. You can see the new section there.
.file "try.c"
.section mysection,"ax",@progbits
.globl try
.type try, @function
try:
pushl %ebp
....
leave
ret
.size try, .-try
.section .rodata
.LC0:
.string "\nIn main\n"
.text
.globl main
.type main, @function
main:
pushl %ebp
.....
ret
.size main, .-main
....

As you see in the above example, the function try is kept in a separate section and not in the .text section as main is.


Also the section can be viewed by readelf i.e. reading the Executable and Linkable format(ELF)
gcc try.c
readelf -a a.out | less

Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
.........
[10] .init PROGBITS 08048278 000278 000017 00 AX 0 0 4
[11] .plt PROGBITS 08048290 000290 000030 04 AX 0 0 4
[12] .text PROGBITS 080482c0 0002c0 0001e0 00 AX 0 0 16
[13] mysection PROGBITS 080484a0 0004a0 000015 00 AX 0 0 1
[14] .fini PROGBITS 080484b8 0004b8 00001b 00 AX 0 0 4
[15] .rodata PROGBITS 080484d4 0004d4 000012 00 A 0 0 4
[16] .data PROGBITS 080494e8 0004e8 00000c 00 WA 0 0 4
..........


(xv) used
Compiler will generate code for the function, even if it finds that the function is not used.

(xvi) weak
  • Attributes in Data Declaration:
(i) aligned
Variable with this attribute will be aligned on amemory address that is an even multiple of the number specified for alignment.
Also default alignment can be set by using the keyword align which has no parameter, instead of aligned. It aligns the variable to largest alignment for any data item supported by hardware.

(ii) deprecated

(iii) mode
Variable with this attribute is sized to match the size of specified mode.

Now u can even declare integer of one byte :) :).. But pointer arithmetic leads to unusual results. :(

modes are : word, byte, pointer.

#include

int main()
{
int iTemp __attribute__((mode(byte)));
printf("\nSize of iTemp = %d \n",sizeof(iTemp));
}

$ gcc trymode.c
$ ./a.out

Size of iTemp = 1

(iv) nocommon

(v) packed
Variable with this attribute has the smallest alignment possible. In struct, a field with this attribute will be allocated with no space between it and the field before it.

ex :
struct record {
char id;
int var[32] __attribute__((packed));
};
The member var of struct record will start 1 byte from the start of the structure.

A struct or union with this attribute takes minimum amount of space possible. It is equivalent to the attribute being apploed to each member of it.

(vi) section
Same as for function

(vii) unused
Tells the complier that the variable may not be used and hence do not issue warnings. :D


(viii) vector_size
A variable with this size is allocated a space equal to the value specified as an argument.
ex : float try __attribute__((vector_size(32)));
Assuming float takes 4 bytes, a block of 8 float variables is created.

IMP!!!! Many things here are very architecture-specific.


Source : GCC : Complete Reference
Page No. 80