[Subject Prev][Subject Next][Thread Prev][Thread Next][Subject Index][Thread Index]

RE: [LI] How pass parameters to function through alarm ......



Hi,
	This is HOW and WHY for things related to alarm() system call. If
you see the structure timer_list ther is a field void (*function)(unsigned
long). This structure is updated for each alarm() system call that appears
in the process. It's basically a doubly linked list . The data portion is
for-if you want to use the same function for various timeouts. You can use
this to distinguish different types of timeouts. If you write two alarm()
system calls in a single process the second value will be kept for sending
SIGALRM. When the alarm(sec) system call is executed sys_alarm() is called
in the kernel. This function calls the do_settimer() function which saves
the pending value(by calling do_gettimer()) and the clears the old timer of
that process by calling del_timer() and then sets the values of different
fields of the real_timer. Now when the timer expires,the function which the
function field of the timer_list points to, is called and executed. So you
can't pass arguments to the handler code you have written. (Think about
interrupt handlers) signals are very much similar to interrupts(analogy).
struct itimerval   {
			struct timeval it_interval;
			struct timeval it_val;
		};

struct timeval     {
			time_t tv_sec;		/* seconds */
			suseconds_t tv_usec;    /* microseconds */

		};

struct timer_list {
			struct timer_list *next;
			struct timer_list *prev;
			unsigned long expires;   /* when this timer will
expire, i.e. when the kernel should send signal to the process */
			unsigned long data;
			void (*function)(unsigned long);
		};

int do_getitimer (int which, struct itimerval  *value )
{
	/* real_timer is a timer_list type structure */
	register unsigned long val, interval;
	switch (which) { 
			 case ITIMER_REAL 
			 interval = current ->it_real_incr;
			 val = 0;
			 start_bh_atomic();
			 if (timer_pending (&current ->real_timer)) { 
			 val = current ->real_timer.expires - jiffies ; 
			 /* look out for negative/zero itimer.. */ 
			if ((long) val <= 0) 
				val = 1; } 
			end_bh_atomic(); 
			break; 
			---------------------------
			--------------------------
			}
		  convert jiffies to tv, both the fileds of value and save
them; /* kernel should handle the pending things */		
  		  return 0;
}
int do_settimer(int which, struct itimerval *value,struct itimerval *ovalue)
{
	-------------------
	--------------------
	convert the fields of value to jiffies;
	if(ovalue && (k=do_gettimer(which,ovalue))<0)   
		return k;	
	switch (which) {
		case ITIMER_REAL:	/* we are concerned with the real
timer not the virtual one and the one used for profiling */
			---------------------------------
			/* clear the current real timer */
			del_timer(&current->real_timer);
			/* This is the why if you write two alarm system
calls in a process the timer value is set equal to the argument value of the
second alarm() call, i.e. the timer is reset */
			- - - - - ----------------------
			/* now set the fields for the current process
pointed by the current pointer */
			current->it_real_value=j;
			current->it_real_incr=i;
			- - - - - - - - -- - -- - - - - - 
 			- - - - - - - - - - - - - - - - -
			current->real_timer.expires=i;
			/* Now add the new real timer to the list for this
process */
			add_timer(&current->real_timer);
			break;
		case - - -:
			- - -- -- - - - - - - - 
			- - - - - - - - - - - -
		}
	return 0; /* if you reach here means everything went right */
}

/* Now here comes the actual thing to which alarm() call passes the
responsibility */

asmlinkage unsigned int sys_alarm(unsigned int seconds)
{
	struct itimerval it_new, /* the new timer which will be kept on the
list because of alarm(); */
	                      it_old; /* conatins the old timer */
	unsigned int oldalarm;
	
	clear the second field(sec) and microsecond filed(usec) for the
interval; /* set to zero */
	set the second filed(sec) of the value = seconds;
	/* now set the REAL TIMER , that's why ITIMER_REAL */
	do_settimer(ITIMER_REAL, &it_new, &it_old);
	/* save the old value, i.e. pending */
	oldalarm=it_old.it_value.tv_sec;
	/* ehh.. We can't return 0 if we have an alarm pending ..*/
	/*And we'd better return too much than too little anyway */
	if(it_old.it_value.tv_usec)
		oldalarm++;
	return oldalarm;	/* Thus alarm call returns the pending
amount */
}

HTH	
Ajit 
----------------------------------------------------------------------------
-------------------------
Best way to learn Linux is to put comments in the source code
___________________________________________________

> -----Original Message-----
> From:	Arun K Desai [SMTP:arun_desai@xxxxxxxxxxxx]
> Sent:	Thursday, January 13, 2000 12:53 PM
> To:	Victor Ustymchuk; Mike Stok; Lyris; LinuxProgram; LinuxIndiaOrg;
> Glynn Clements
> Subject:	[LI] How pass parameters to function through alarm ......
> 
> Hi all,
> 
> I am working on Redhat Linux 6.0 & C.
> 
> I am using alarm system call..
> 
>   signal(SIGALRM,fun);/* fun is function 
>                               adrress*/
>   alarm(2);
>   for( ; ;)
> 
> 
> 
> 
> fun(int i)
> {
> printf("Passed Val Is: %d\n",i);
> }
> 
> 
> My prblem is how to pass a value(int parameter) to function(fun) which set
> in signal alarm?????
> 
> 
>            Thax...
>                    Best Regards,
>                             Arun.K.Desai.
> 
> 
> 
> LYCOShop is now open. On your mark, get set, SHOP!!!
> http://shop.lycos.com/
> --------------------------------------------------------------------
> The Linux India Mailing List Archives are now available.  Please search
> the archive at http://lists.linux-india.org/ before posting your question
> to avoid repetition and save bandwidth.
--------------------------------------------------------------------
The Linux India Mailing List Archives are now available.  Please search
the archive at http://lists.linux-india.org/ before posting your question
to avoid repetition and save bandwidth.