[comp.sys.amiga.tech] Wait

dlarson@blake.acs.washington.edu (Dale Larson) (10/06/89)

[go ahead, eat my breakfast]

In tryig to write some code which does not busy-loop but does need to check
on several events, I am trying to use Wait().  As the simplest first step,
I
	Wait(timerport->mp_SigBit);

This does not work (hangs), but 
	
	WaitPort(timerport);

does work properly.  Could someone please give me a clue (the RKM's and
AutoDocs just say "if you need to wait for more than one message, use
Wait() rather than WaitIO()" but do not explain how to use it for this
purpose).  

If it matters, I am using Manx 3.6a (until my beta 5.0 arrives :-)


-- 
	    A lack of prior planning on the part of any programmer 
		       always constitutes an emergency.
	
           Digital Teddy Bear      dlarson@blake.acs.washington.edu

mks@cbmvax.UUCP (Michael Sinz - CATS) (10/06/89)

In article <3930@blake.acs.washington.edu> dlarson@blake.acs.washington.edu (Dale Larson) writes:
>[go ahead, eat my breakfast]
>
>In tryig to write some code which does not busy-loop but does need to check
>on several events, I am trying to use Wait().  As the simplest first step,
>I
>	Wait(timerport->mp_SigBit);

Note that mp_SigBit is the BIT NUMBER and the Wait() used the bit mask so
that you can wait on multiple signals.  So...

        Wait(1L << (timerport->mp_SigBit));

or if you have a few more...

        Wait(	(1L << (timerport->mp_SigBit)) |
		(1L << (otherport->mp_SigBit)) |
		(1L << (inputport->mp_SigBit))	);

>
>This does not work (hangs), but 
>	
>	WaitPort(timerport);
>
>does work properly.  Could someone please give me a clue (the RKM's and

  [remainder deleted...]

>	
>           Digital Teddy Bear      dlarson@blake.acs.washington.edu

/----------------------------------------------------------------------\
|      /// Michael Sinz -- CATS/Amiga Software Engineer                |
|     ///  PHONE 215-431-9422  UUCP ( uunet | rutgers ) !cbmvax!mks    |
|    ///                                                               |
|\\\///          When people are free to do as they please,            |
| \XX/                they usually imitate each other.                 |
\----------------------------------------------------------------------/

dlarson@blake.acs.washington.edu (Dale Larson) (10/06/89)

I wish I could have found the answer in the docs somewhere, but louie was
kind enough to help me and here is his reply (I haven't tried it yet (am
at work) but don't doubt that it is correct).  Thank you louie!

----
From louie@sayshell.umd.edu Fri Oct  6 06:06:24 1989

In article <3930@blake.acs.washington.edu> you write:
>	Wait(timerport->mp_SigBit);
>This does not work (hangs), but 
>	WaitPort(timerport);
>does work properly.

Wait() takes a bit mask, not a signal bit number.  So you should have used:

	Wait(1L<<timerport->mp_SigBit);

To wait for more than one signal bit, just OR the bits together:

	what = Wait((1L<<timerport->mp_SigBit) | (1L<<consoleport->mp_SigBit));

Wait() returns a bit mask of which signals occured and caused it to wake up.

louie

-----




-- 
	    A lack of prior planning on the part of any programmer 
		       always constitutes an emergency.
	
           Digital Teddy Bear      dlarson@blake.acs.washington.edu

cmcmanis%pepper@Sun.COM (Chuck McManis) (10/07/89)

In article <3930@blake.acs.washington.edu> (Dale Larson) writes:
>	Wait(timerport->mp_SigBit);
>This does not work (hangs), but 

Try 
	Wait(1 << timerport->mp_SigBit);

Note that SigBit is the bitnumber and you have to shift a 1 bit left by
that number to get the appropriate signal mask.

--Chuck McManis
uucp: {anywhere}!sun!cmcmanis   BIX: cmcmanis  ARPAnet: cmcmanis@sun.com
These opinions are my own and no one elses, but you knew that didn't you.
"If I were driving a Macintosh, I'd have to stop before I could turn the wheel."

fgd3@jc3b21.UUCP (Fabbian G. Dufoe) (10/07/89)

In article <3930@blake.acs.washington.edu>, dlarson@blake.acs.washington.edu (Dale Larson) writes:
> 	Wait(timerport->mp_SigBit);
> 
> This does not work (hangs), but 

     You need to use
     Wait(1<<timerport->mp_SigBit);

Wait() requires a signal mask, not just the bit number.  By shifting 1 left
as many times as the value in mp_SigBit you create the mask you need.  If
you need to Wait() for more than one signal you can OR the masks:

     Mask = (1<<timerport->mp_SigBit | 1<<otherport->mp_SigBit);
     Wait(Mask);

I hope this answers your question.

--Fabbian Dufoe
  350 Ling-A-Mor Terrace South
  St. Petersburg, Florida  33705
  813-823-2350

UUCP: ...uunet!pdn!jc3b21!fgd3

bradch@microsoft.UUCP (Bradford Christian ms1) (10/07/89)

In article <3930@blake.acs.washington.edu> dlarson@blake.acs.washington.edu (Dale Larson) writes:
>
>In tryig to write some code which does not busy-loop but does need to check
>on several events, I am trying to use Wait().  As the simplest first step,
>I
>	Wait(timerport->mp_SigBit);

Use:	Wait(1L << timerport->mp_SigBit);

You can OR togeather all the bits you need to wait on like this:

	Wait((1L << timerport1->mp_SigBit) | (1L << timerport2->mp_SigBit));

Thanks for not busy looping!

	BradCh

dlarson@blake.acs.washington.edu (Dale Larson) (10/14/89)

Thanks for the hundreds of responses to my Wait() query!

The more than a dozen follow-ups make me curious 'bout a few things
though.  

	1)  Would deleting the original posting after I recieved and answer
            and posted a summary have prevented anyone non-local from seeing
	    (and hence, replying) to it?

	2)  Do you have to say "Email, please, will post summary?"

	3)  What documentation were you guys using?  Or did you spend
	    the first year you had an Amiga memorizing the RKM's and
	    creating a mental cross-reference?  (I've been trying to
	    write code for the last 2 1/2 years, would it have been more
	    productive to memorize?)  Or was the dearth of replies a 
	    function of how many hours you knew it might take me to
	    discover the answer for myself?



-- 
	    A lack of prior planning on the part of any programmer 
		       always constitutes an emergency.
	
           Digital Teddy Bear      dlarson@blake.acs.washington.edu

kxs5829@ultb.UUCP (K.X. Saunders) (10/31/89)

Hi,

	Does anyone know how to find the *Window pointer of a process
running in a cli window?

				Thanks,
			Kyle

			kxs5829@ultb.isc.rit.edu

dillon@POSTGRES.BERKELEY.EDU (Matt Dillon) (10/31/89)

	This is from my sup32.lib ...  I wrote it a year or two
    ago.

				-Matt
    
/*
 *  CONWIN.C
 *
 *  Win = GetConWindow()
 *
 *  Returns console window associated with the current task or NULL if
 *  no console task associated.
 *
 *  The intuition.library and graphics.library must be openned.
 */

#include <proto/all.h>
#include <exec/memory.h>

typedef struct StandardPacket STDPKT;
typedef struct InfoData       INFODATA;
typedef struct Window	      WIN;
typedef struct Process	      PROC;
typedef struct MsgPort	      PORT;
typedef struct Message	      MSG;

/*
 *  GETCONWINDOW()
 *
 *  Return the window used by the console of the current process.  We can
 *  use our process's message port as the reply port since it is a
 *  synchronous packet (we wait for the result to come back).  WARNING:
 *  This routine does not check if the 'console' of the current process
 *  is really a console device.
 *
 *  The DISK_INFO packet is sent to the console device.  Although this
 *  packet is normally used to retrieve disk information from disk
 *  devices, the console device recognizes the packet and places a pointer
 *  to the window in id_VolumeNode of the infodata structure.  A pointer
 *  to the console unit is also placed in id_InUse of the infodata structure.
 */

WIN *
GetConWindow()
{
    PROC	*proc;
    STDPKT	*packet;
    INFODATA	*infodata;
    long	result;
    WIN 	*win;

    proc   = (PROC *)FindTask(NULL);
    if (!proc->pr_ConsoleTask)
	return(NULL);
    /*
     *	NOTE: Since DOS requires the packet and infodata structures to
     *	be longword aligned, we cannot declare them globally or on the
     *	stack (word aligned).  AllocMem() always returns longword
     *	aligned pointers.
     */

    packet   = (STDPKT   *)AllocMem(sizeof(STDPKT)  , MEMF_CLEAR|MEMF_PUBLIC);
    infodata = (INFODATA *)AllocMem(sizeof(INFODATA), MEMF_CLEAR|MEMF_PUBLIC);

    packet->sp_Msg.mn_Node.ln_Name = (char *)&(packet->sp_Pkt);
    packet->sp_Pkt.dp_Link = &packet->sp_Msg;
    packet->sp_Pkt.dp_Port = &proc->pr_MsgPort;
    packet->sp_Pkt.dp_Type = ACTION_DISK_INFO;
    packet->sp_Pkt.dp_Arg1 = CTOB(infodata);
    PutMsg((PORT *)proc->pr_ConsoleTask, (MSG *)packet);
    WaitPort(&proc->pr_MsgPort);
    GetMsg(&proc->pr_MsgPort);

    result = packet->sp_Pkt.dp_Res1;
    win = (WIN *)infodata->id_VolumeNode;
    /* note: id_InUse holds a pointer to the console unit also */
    FreeMem(packet  , sizeof(STDPKT));
    FreeMem(infodata, sizeof(INFODATA));
    if (!result)
	return(NULL);
    return(win);
}

a1406@mindlink.UUCP (Elise Tarrant) (03/16/90)

> bdiscoe writes:
> 
> Msg-ID: <1990Mar16.214401.1738@spectre.ccsf.caltech.edu>
> Posted: 16 Mar 90 21:44:01 GMT
> 
> Org.  : California Institute of Technology
> Person: Ben W. Discoe
> 
> How do you Wait() on several ports simultaneously?  I know how to wait on,
> say, the serial device, console device and an IDCMP individually, but what
> I really need to do is wait on a message from any one of them.
> 
> I tried:  waitflags = <port 1's bit> | <port 2's bit> |.... ;
>           Wait(waitflags);
> but this didn't seem to work.
> 
> -Ben "But I READ the manual!  Honest!"

You almost had it. Instead of trying to or the bits into one flag
to wait for, set up two flags and then or in the call to wait(), like this.
wait1flag = <port 1's mp_SigBit>;
wait2flag = <port 2's mp_SigBit>;
wait(wait1flag | wait2flag);

bdiscoe@tybalt.caltech.edu (Ben W. Discoe) (03/17/90)

How do you Wait() on several ports simultaneously?  I know how to wait on,
say, the serial device, console device and an IDCMP individually, but what
I really need to do is wait on a message from any one of them.

I tried:  waitflags = <port 1's bit> | <port 2's bit> |.... ;
	  Wait(waitflags);
but this didn't seem to work.

-Ben "But I READ the manual!  Honest!"

peter@cbmvax.commodore.com (Peter Cherna) (03/17/90)

In article <1990Mar16.214401.1738@spectre.ccsf.caltech.edu> bdiscoe@tybalt.caltech.edu (Ben W. Discoe) writes:
>How do you Wait() on several ports simultaneously?  I know how to wait on,
>say, the serial device, console device and an IDCMP individually, but what
>I really need to do is wait on a message from any one of them.
>
>I tried:  waitflags = <port 1's bit> | <port 2's bit> |.... ;
>	  Wait(waitflags);
>but this didn't seem to work.

You can WaitPort() on a port, but you can only Wait() on a signal.
To be clear, you wait on the signal mask (for example 0000000010000000 binary)
and not on the signal bit number (for example signal #7).

So you see constructs like this all the time

	Wait( 1 << msgport->mp_SigBit );

which converts the signal bit number to a bit mask.  So if you have
multiple ports, say arexxport, intuiport, and timerport, you might say

	timermask = ( 1 << timerport->mp_SigBit );
	arexxmask = ( 1 << arexxport->mp_SigBit );
	intuimask = ( 1 << intuiport->mp_SigBit );

	signalmask = Wait( timermask | arexxmask | intuimask );

	if (signalmask & timermask)
	{
		/*  got a msg at timerport */
	}

	if (signalmask & arexxmask)
	{
		/*  got a msg at arexxport */
	}

	if (signalmask & intuimask)
	{
		/*  got a msg at intuiport */
	}

>-Ben "But I READ the manual!  Honest!"

     Peter
--
     Peter Cherna, Software Engineer, Commodore-Amiga, Inc.
     {uunet|rutgers}!cbmvax!peter    peter@cbmvax.cbm.commodore.com
My opinions do not necessarily represent the opinions of my employer.

sjorr@rose.waterloo.edu (Stephen Orr) (03/18/90)

>You almost had it. Instead of trying to or the bits into one flag
>to wait for, set up two flags and then or in the call to wait(), like this.
>wait1flag = <port 1's mp_SigBit>;
>wait2flag = <port 2's mp_SigBit>;
>wait(wait1flag | wait2flag);

This is functionally the same as what he was doing, please note
however that the initialization of wait1flag and wait2flag
should be

	wait1flag = 1<<mp_SigBit &
	wait2flag = 1<<mp_SigBit

Further the wait call (which should be capitolized) returns
a bitfield to tell you which 'waits' succeeded, the wait call
should then be

	ports = Wait(wait1flag | wait2flag);

Which justifies the use of the waitnflag variables as you can
now see which port(s) succeeded with

	if (ports & wait1flag) { /* do stuff */
	}
	if (ports & wait2flag) { /* do other stuff */
	}

Note: it is very possible for more than 1 port to succeed at
the same time.

					Stephen Orr
					SandIsoft

peck@ral.rpi.edu (Joseph Peck) (11/01/90)

Well, time to ask another programming question. 

Is there a nice way using Lattice C to perform a Wait type function
that puts my program to sleep until a given scanline is passed?

Basically, I am using DrawImage to place a small picture on the    
screen and move it around.  I am using WaitTOF() to keep things
moving around at 60Hz, but DrawImage can't finish the draw in time
near the top of the screen (flicker, and random color splotches
depending on what bitplane it has gotten through by then).

I want to avoid assembler for now, but I didn't see a way to 
utilize the copper for this in C in the RKM.

Any clues?

Thanks,
 Joe Peck
 peck@ral.rpi.edu
  

markv@kuhub.cc.ukans.edu (11/08/90)

> Well, time to ask another programming question. 
> 
> Is there a nice way using Lattice C to perform a Wait type function
> that puts my program to sleep until a given scanline is passed?

Not really.  WaitBOVP() gets you sooner than WaitTOF() but it busy
waits by looping looking at the VPOS register.  The only asynchrounus
way to wait for a specific line is to use the Copper to cause an
interrupt or something similar.  But not pretty.
 
> Basically, I am using DrawImage to place a small picture on the    
> screen and move it around.  I am using WaitTOF() to keep things
> moving around at 60Hz, but DrawImage can't finish the draw in time
> near the top of the screen (flicker, and random color splotches
> depending on what bitplane it has gotten through by then).

Even if you can get the CPU the instant you past the scan line you are
limited in how many bits you can move over time.  Its quite a few, but
a large multi-bitplane area is a problem.

> I want to avoid assembler for now, but I didn't see a way to 
> utilize the copper for this in C in the RKM.

One system call you can try is QBSBlit().  You enqueue a BltNode with
a beamsync value.  When your somewhere past that line a function you
specify gets called and you can do your blit.  This of course requires
"blitter arithmatic" which can be confusing but faaasssttt.  If you
can get your blit to be done in ascending mode, you can gain extra
time by haveing the blitter "chase" the display DMA or vice versa
(which to do depends one which is getting more cycles, you want the
slower to chase the faster).

This is because display hashing only occurs when the blitter passes
the display DMA or vice versa.

However, sooner or later you just not going to have enough cycles and
double buffering is the only solution, but it has its own problems
(like keeping intuition happy).

> Any clues?
> 
> Thanks,
>  Joe Peck
>  peck@ral.rpi.edu
>   
-- 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Mark Gooderum			Only...		\    Good Cheer !!!
Academic Computing Services	       ///	  \___________________________
University of Kansas		     ///  /|         __    _
Bix:	  markgood	      \\\  ///  /__| |\/| | | _   /_\  makes it
Bitnet:   MARKV@UKANVAX		\/\/  /    | |  | | |__| /   \ possible...
Internet: markv@kuhub.cc.ukans.edu
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~