[comp.unix.ultrix] looking for usleep

bruce@servio.UUCP (Bruce Schuchardt) (10/17/89)

I have a queue of programs I would like to port to my DECstation 3100 that
require a usleep() function for implementing delays.  I can't find a
usleep() function under ULTRIX, and am hoping some kind person will share
their implementation with me, or point me to the ULTRIX libxx that has one.

Please e-mail responses.  Thanks!


-- 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  Bruce Schuchardt          Ph: (503) 629-8383
  Servio Logic              bruce@servio.SLC.COM
  Beaverton, OR             uunet!servio!bruce

pete@othello (Pete Schmitt) (10/18/89)

Maybe this was discussed before, but why not use napms() in the libcursesX.a
library?


-pete

muth@buffer.dec.com (Bill Muth) (10/18/89)

    Here is a macro for usleep() which appeared in comp.sources.x in the
    program xchomp.

    #ifdef ULTRIX
    #include <sys/time.h>
    EXTERN struct timeval   st_delay;
    #define usleep(x)       { st_delay.tv_usec = (x); st_delay.tv_sec = 0; \
                              select(32, NULL, NULL, NULL, &st_delay); }
    #endif



						    Bill

michaud@decvax.dec.com (Jeff Michaud) (10/19/89)

>     Here is a macro for usleep() which appeared in comp.sources.x in the
>     program xchomp.
> 
>     #ifdef ULTRIX
>     #include <sys/time.h>
>     EXTERN struct timeval   st_delay;
>     #define usleep(x)       { st_delay.tv_usec = (x); st_delay.tv_sec = 0; \
>                               select(32, NULL, NULL, NULL, &st_delay); }
>     #endif

	Note however that select will return a invalid argument error if the of
	u-seconds you give is equiv to a second or more.  So something along

		#ifdef ultrix
		#define usleep(x)	\
			{ struct timeval delay;				\
				delay.tv_sec  = (int)(x) / 1000000;	\
				delay.tv_usec = (int)(x) % 1000000;	\
				select(0, (int *)0, (int *)0, (int *)0, &delay); }
		#endif

	Note also that I use 0 as the first argument to select().  Also note that
	I used a lowercase "ultrix" for the #ifdef as "ultrix" is predefined by
	ULTRIX's cpp but "ULTRIX" isn't.

	To make this really generic it should be defined as a function.  As a
	macro things like:

		if( ... )
			usleep(...);
		else
			....

	because the "usleep(...);" is two statements, ie. a compound statement and
	the null statement.  This can be worked around if you use an explicit
	compound statement around the "usleep(...);" while keeping your code
	portable.

	The question I have is, is the real usleep() function defined to be
	interruptable?  select() is (but that too can be fixed by explicitly
	blocking signals or by restarting the select() (taking into account
	time already slept).

/--------------------------------------------------------------\
|Jeff Michaud    michaud@decwrl.dec.com  michaud@decvax.dec.com|
|DECnet-ULTRIX   #include <standard/disclaimer.h>              |
\--------------------------------------------------------------/

zvr@natasha.cs.wisc.EDU (Alexios Zavras) (10/19/89)

In article <5508@shlump.nac.dec.com>, michaud@decvax.dec.com (Jeff
Michaud) writes:
> 	To make this really generic it should be defined as a function.  As a
> 	macro things like:
> 		if( ... )
> 			usleep(...);
> 		else
> 			....
> 	because the "usleep(...);" is two statements, ie. a compound statement and
> 	the null statement.  This can be worked around if you use an explicit
> 	compound statement around the "usleep(...);" while keeping your code
> 	portable.

The way to #define a macro as two or more statements,
without having this problem is:

#define macro(x)	do { stmt1(x); stmt2(x); ... } while (0);

So, the definition of usleep() looks like:

/*=========================================================================*/

#ifdef  ultrix

#ifndef _TYPES_
#include    <sys/types.h>
#endif  /* _TYPES_ */
#ifndef __XTIME__
#include    <sys/time.h>
#endif  /* __XTIME__ */

#define usleep(usec)
        do                                                              \
        {                                                                \
            struct timeval  usl_delay;                                    \
            usl_delay.tv_sec  = (int) (usec) / 1000000;                    \
            usl_delay.tv_usec = (int) (usec) % 1000000;                     \
            (void) select(0,(fd_set *)0,(fd_set *)0,(fd_set *)0, &usl_delay);\
        } while (0);

#endif  /* ultrix */

/*=========================================================================*/


> |Jeff Michaud    michaud@decwrl.dec.com  michaud@decvax.dec.com|

-- zvr --
	+-----------------------+	Alexios Zavras
	| Life is once, forever |	zvr@cs.wisc.edu
	+-----------------H C-B-+	zavras@cs.wisc.edu
Live from:
Wisconsin: land of Orson Welles, Frank Lloyd Wright,
		   Harry Houdini  and Spencer Tracy
	       (of Joe McCarthy, too, but we try to forget that)

zvr@natasha.cs.wisc.EDU (Alexios Zavras) (10/20/89)

In article <8896@spool.cs.wisc.edu>, I wrote:
> #define macro(x)	do { stmt1(x); stmt2(x); ... } while (0);

and later...

> #define usleep(usec)
>         do                                                              \
>         {                                                                \
>             struct timeval  usl_delay;                                    \
>             usl_delay.tv_sec  = (int) (usec) / 1000000;                    \
>             usl_delay.tv_usec = (int) (usec) % 1000000;                     \
>             (void) select(0,(fd_set *)0,(fd_set *)0,(fd_set *)0,
&usl_delay);\
>         } while (0);

Sorry, I must have been asleep! :-)

You naturally have to omit the final `;' in both cases, i.e.:

#define macro(x)	do { stmt1(x); stmt2(x); ... } while (0)

Then you can easily write 
	if (...)
		macro(...);
	else
		...

without any problems...

Sorry about that,
-- zvr --
	+-----------------------+	Alexios Zavras
	| Life is once, forever |	zvr@cs.wisc.edu
	+-----------------H C-B-+	zavras@cs.wisc.edu
Live from:
Wisconsin: land of Orson Welles, Frank Lloyd Wright,
		   Harry Houdini  and Spencer Tracy
	       (of Joe McCarthy, too, but we try to forget that)