Hi,
I am trying to implement the synchronize feature of java using C. I am using a semaphore for the same. I have a wrapper called "synch" to which I pass the function pointer(any_fn). This pointer points to the function (my_fn) which needs to be synchronized.
However to create the semaphore I need to pass a semkey which should be a indicative of the function (my_fn). I cannot use the address of this function (my_fn) because every binary will execute in its own address space and the pointer will always be different, and hence the semkey will also be different.
Can anyone help me generate this semkey.
OK, use 7,564,263.
I'm tempted to end my reply there, but I guess some explanation is in order. 
Suppose for a moment that your my_fn function was going to be used in a single executable so that the semaphore would only need to syncronize among simultaneous instances of that single executable. In that case, you could go ahead and use the address of the function. But what is magic about that address? The loader could, in theory, put another function in another executable at the same address.
There are billions of possible key values, but I have never seen a system that needs more than a few dozen. That makes this a small problem. Just pick something and go with that. It's like picking a name for your function or picking a file name.
Collisions are possible and you should be ready for them. Always test your return codes. And I would put the value in a config file and read it once. This makes it easy to change if that is ever needed. The my_fn could do this internally by using a static value initialized to zero. If zero, read the value and store it in the static variable.
Or you can just store the key as a constant in my_fn and risk the need to recompile should a collision occur. I've done that too.
There is also a function called ftok() that you should look at. It takes a pathname and a small integer and returns a key. I never use it, but if I don't mention it, someone else will. 
Hi Perderabo,
thanks for the reply.
However, initially i started with the idea of ftok. but since i am creating the semaphore in the synch function itself, i m calling the ftok there and so it will always return te same key.
then after this i took up the second approach, about the static variable, however i do not find this graceful and so i have posted this here. having a static variable is ungraceful ( i feel) because someone who wants to use my synch function may set the value of this static variable to a existing value(vaue being used in some other function).
the graceful way i feel is to have some kind of a mechanism to get the key from the function name itself. And offcourse this key is to be generated in the synch function ( or be made availabel to it). So I thought of trying to pass it as the function argument. But again I am passing a function pointer to synch, so dont know how to make this argument available to synch.
Hope, I have made myself clear.
Thanks and waiting patiently for a cool solution.
I may be wrong in understanding the situation but please let me know if I am.
When I went through the post I read statement as stated by linuxpenguin " .... and hence the semkey will also be different " which concludes to me that he is in need of a semkey which should be unique.
But later in his post he says "... i m calling the ftok there and so it will always return the same key".
Is it that he is looking for a dynamic semkey ... please clarify ?
Prasad,
I know I have made it confusing. But very true, I am looking for a dynamic kind of a semkey, which will always have the same value if and only if the synch function pointer points to a particular function. This semkey will have a different value if the function pointer points to another function.
my_fn
fn1
fn2
are three functions
any_fn points to one of these at a time.
from wherever I call synch(any_fn)
if any_fn is my_fn then semkey should be unique say sk
if any_fn is fn1 then semkey should be unique say sk1
if any_fn is fn2 then semkey should be unique say sk2
and so on
if I again synch (any_fn) twice thrice or as many times with any_fn pointing to say fn2, then semkey should always be sk2
if i call synch(any_fn) any number of times with any_fn pointing to fn1 then semkey should always be sk1
I hope this makes it much clear now.
For more clarity here is the code I am using
/****************** myincludes.h**********************/
#include<stdio.h>
#include<sys/types.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include<strings.h>
#include<stdarg.h>
#include <errno.h>
#include <sys/ipc.h>
#include <sys/sem.h>
/*****EOF *****/
/************** synch.c ******************************/
#include"myincludes.h"
/* This is just a normal header file with standard .h files in it */
int proj; /* This is the one I am currently using and want to do away with */
struct sembuf sb[2]={0,0,IPC_NOWAIT, 0,1,SEM_UNDO};
int synch(any_fn)
int (*any_fn)();
{
int semid;
key_t semkey;
semkey = ftok("/local/psimulation/hemant",proj);
semid=semget(semkey,1,IPC_CREAT|0666);
if(semid < 0) {
perror("Error creating semaphore\n");
exit(-1);
}
if( (semop(semid,&sb,2)) < 0 ) {
perror("Semop error");
exit(-1);
}
printf("resource locked\n");
(any_fn)();
sb[0].sem_op = -1;
sb[0].sem_flg = SEM_UNDO;
if( (semop(semid,&sb,2)) < 0 ) {
perror("Semop error\n");
exit(-1);
}
printf("resource unlocked\n");
sb[0].sem_op = 0;
sb[0].sem_flg = IPC_NOWAIT;
return;
}
/*****EOF *****/
/************** p1.c ******************************/
/* cc -o p1 p1.c synch.c */
#include"myincludes.h"
extern int proj;
int myfn()
{
printf("p1.myfn\n");
while(1) {
sleep(5);
break;
}
}
void main(argc, argv)
int argc;
char *argv[];
{
proj=31; /* unique for myfn */
synch(myfn);
}
/*****EOF *****/
/*******************************************************/
Now execute p1 simultaneously. This is working. I want a better solution for proj and would like to have the semkey created in synch.
Code tags added for readability -- Perderabo
I tried a sample program with an array of function pointers and when I de-referenced it at any instances only the required code was executed.
Definitely the function pointer array contents were different but constant.
I might have wrongly analyzed the post.... but does this output helps you in anyway.
#include <stdio.h>
void (*fn[3])();
void my_fn()
{
printf ("my_fn\n" ) ;
}
void fn1()
{
printf ("fn1\n" ) ;
}
void fn2()
{
printf ("fn2\n" ) ;
}
main ( )
{
fn[0]=my_fn;
fn[1]=fn1;
fn[2]=fn2;
(*fn[0])();
(*fn[1])();
(*fn[2])();
}
Output:
my_fn
fn1
fn2
Is it possible to then take fn[0],fn[1],fn[2].... as semkey?
After re-going through the post again, I understand that my previous reply was in correct.
Apologies for providing an unsuitable answer.
ok Prasad,
Now that you have got what I want, hope you have a soln to this one.