Saturday, February 20, 2010

Exceptional exception handling in C++

#include

using namespace std;

//Global
int a = 20;

void foo()
try {
throw a;
}
catch(int &x)
{
// You can't modify value of "a"
x = 10;
}

int main()
{
foo();
cout<<"A="< }

A=20 !!!!
When you write "throw a", an invisible, phantom exception object gets created. You pass reference to that object and hence any change made to original object have no effect.

Friday, February 19, 2010

Mutex v/s Semaphore v/s Spinlock

Similarity

- All are used for synchronization

Difference

Mutex provides one person to access a resource at a time, others must wait in a queue. Once person is done, the guy next in the queue acquire the resource.
So access is serial, one guy after other.

Semaphore provides more than one(up to N) guys to access N resources. So it gives you parallel access to a resource.

Spinlock is an aggressive mutex. In mutex, if you find that resource is locked by someone else, you (the thread/process) switch the context and start to wait(non-blocking).
Whereas spinlocks do not switch context and as soon as resource is free, they go and grab it. In this process of spinning, they consume many CPU cycles. Also, on a uni-processor machine they are useless and perform very badly (do I need to explain that?).

Thursday, February 4, 2010

GL: Question

- fun(int, int);
fun(char, char)
Are they overloaded properly?

- Using static variable in a member function?

- Finding the common node of two link lists?

- Implement BFS, DFS?

- Inorder, preorder is DFS or BFS?

- What is a heap?

- Deleting a node in BST?

- Difference of memcpy() and strcpy()

Wednesday, January 6, 2010

C Structures: Calculating offset of an element

Let's say we have the following structure:

struct
{
int a;
char c;
} example;

To calculate offset of 'c', we have following ways:

1. Use the macro offsetof() defined in header file stddef.h.
unsigned int x = offsetof(struct example, c);
This macro takes care of padding of elements done by the compiler.

2. Other way to get the offset f c is:
// C snippet
example var, example *ptr;
ptr = &var;
offset = &(ptr->c)- &(ptr->a)
//

------|base_addr = 0x0000
int a |
------|addr = (0x0000 + 0x0004)
int c |
------|addr = (0x0004 + 0x0004)

We are getting the distance of 'c' from base of the structure. So, address &(ptr->c) should be calcuated by compile as: base_address of var + distance of 'c' from base
If we somehow set base_addr as zero, we will get the offset i.e. 0x0004.

A hack to accomplish this result is as follows:
#define POINTER = ((struct example*)(0))
unsigned int x = (unsigned int) & (POINTER->c);

We are typecasting an address '0' pointing to a type of data 'struct example'.
Now when you do (x)->c, it is equivalent to: BASE_ADDESS(x) + size_of_data elements preceding 'c'. We are tricking the compiler by giving BASE_ADDRESS as zero.

This hack may be incorrect if element padding is done by the compiler.

Tuesday, December 15, 2009

Signals in Linux

- List of signals: $kill -l
- You can't handle SIGSTOP and SIGKILL. You can't priorities which signal to handle.
- Signals are generated by setting the appropriate bit in the task_struct's signal field. If the process has not blocked the signal and is waiting but interruptible (in state Interruptible) then it is woken up by changing its state to Running and making sure that it is in the run queue. (linuxhq.com)
- Signals that are sent to a process if an illegal flow of execution happens, are synchronous. They are also called trap e.g. illegal memory access.
- Asynchronous signals are also called interrupts and are sent from a process to another process or thread-to-thread.