English Amiga Board


Go Back   English Amiga Board > Coders > Coders. General

 
 
Thread Tools
Old 17 June 2015, 04:33   #1
tygre
Returning fan!
 
tygre's Avatar
 
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 1,434
Interrupts and Multitasking: Examples?

Hi all!

I am looking for (simple ) examples of interrupt and multitasking programming in C...

What I would like to do is to have a function that polls the status of another program (through ARexx) and, if this status changes, "interrupts" a scanf waiting for user-input... or something like that

Could anyone direct me to examples? Aminet is certainly a treasure trove of such examples but maybe someone could point me to the best places?

Thanks!
tygre is offline  
Old 17 June 2015, 22:33   #2
kamelito
Zone Friend
 
kamelito's Avatar
 
Join Date: May 2006
Location: France
Posts: 1,801
You might Have this in the RKRM examples, search for them in Fred Fish discs or Amiga developer cd.
Kamelito
kamelito is offline  
Old 18 June 2015, 11:28   #3
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,500
Quote:
Originally Posted by tygre View Post
if this status changes, "interrupts" a scanf waiting for user-input... or something like that
Interrupting a clib scanf() on the Amiga is usually not possible. The process is waiting in the dos.library Read() function until a new character is available.

You would have to write your own console to handle user-input, e.g. by using console.device/input.device...
phx is offline  
Old 11 July 2015, 01:48   #4
tygre
Returning fan!
 
tygre's Avatar
 
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 1,434
Hi Kamelito and Phx!

Thanks a lot! Ah, I thought that it would be simple ;-)

Cheers!
tygre is offline  
Old 25 August 2015, 06:02   #5
tygre
Returning fan!
 
tygre's Avatar
 
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 1,434
Hi all!

I am sorry to "bump" this thread but I need help... After scrounging the Internet for example and references, I managed to put this function together... it opens the console.device and wait for character from the keyoard

Now, its problems are that, when I run it from a program running in a Shell:
- First, it "clears" the Shell and the window is not "auto refresh" anymore so, whatever was printed before in the Shell "disappears" but will reappear if I resize the window.
- Second, when it exits, the Shell (and its window) cannot be closed and nothing can be written to it. It seems that the whole Shell window is "frozen".

I must certainly misunderstood something but, frankly, I thought it would be simpler to read a chararcter from the Console than this piece of code Yet, I meed such a code because I want to handle signals from other processes myself in the Wait() .

Please help!

Code:
char controls_wait_for_user(void)
{
	struct MsgPort    *consoleMP        = NULL;
	struct IOStdReq   *consoleIO        = NULL;
	int                open_result      = -1;
	unsigned long      console_signal   = 0UL;
	unsigned long      break_signal     = 0UL;
	char               console_data     = '\0';
	ULONG  			   received_signals = 0L;

	consoleMP = CreateMsgPort();
	if(consoleMP == NULL)
	{
		fprintf(stderr, "Error in controls_wait_for_user(), could not create message port\n");
		goto _RETURN_ERROR;
	}

	consoleIO = CreateIORequest(consoleMP, sizeof(struct IOStdReq));
	if(consoleIO == NULL)
	{
		fprintf(stderr, "Error in controls_wait_for_user(), could not create I/O request\n");
		goto _RETURN_ERROR;
	}

	consoleIO->io_Data   = _get_CON_window(Input());
	consoleIO->io_Length = sizeof(struct Window);
	if((open_result = OpenDevice("console.device", CONU_STANDARD, (struct IORequest *)consoleIO, CONFLAG_DEFAULT)) != 0)
	{
		fprintf(stderr, "Error in controls_wait_for_user(), could not access console with error %d\n", open_result);
		goto _RETURN_ERROR;
	}
	
	while(TRUE)
	{
		consoleIO->io_Command = CMD_READ;
		consoleIO->io_Flags   = IOF_QUICK;
		consoleIO->io_Length  = 1 * sizeof(char);
		consoleIO->io_Data    = (APTR)&console_data;

		printf("Here\n");
		SendIO((struct IORequest *)consoleIO);

		received_signals = Wait((1L << consoleMP->mp_SigBit) | SIGBREAKF_CTRL_C);
		if((received_signals & SIGBREAKF_CTRL_C) == SIGBREAKF_CTRL_C)
		{
			break;
		}
		printf("character = %c\n", console_data);
	}

	goto _RETURN_OK;
	_RETURN_OK:
		// CloseDevice((struct IORequest *)consoleIO);
		DeleteIORequest(consoleIO);
		DeleteMsgPort(consoleMP);
		return '0';

	goto _RETURN_ERROR;
	_RETURN_ERROR:
		if(open_result != 0)
		{
			// CloseDevice((struct IORequest *)consoleIO);
		}
		if(consoleIO != NULL)
		{
			DeleteIORequest(consoleIO);
		}
		if(consoleMP != NULL)
		{
			DeleteMsgPort(consoleMP);
		}
		return '0';
}

Last edited by tygre; 25 August 2015 at 06:07. Reason: More details
tygre is offline  
Old 25 August 2015, 18:21   #6
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,500
I guess the probem is _get_CON_window(). That looks suspicious. You are hijacking your current shell window and use it with a second console. I'm not surprised about any problems.

Try to open a new window for your console. The following modification worked for me:
Code:
#include <stdio.h>
#include <dos/dos.h>
#include <devices/conunit.h>
#include <intuition/intuitionbase.h>
#include <intuition/intuition.h>
#include <proto/exec.h>
#include <proto/intuition.h>

struct NewWindow newconwin = {
  10,10,620,180,-1,-1,
  CLOSEWINDOW,
  WINDOWDEPTH|WINDOWSIZING|WINDOWDRAG|WINDOWCLOSE|SIMPLE_REFRESH|ACTIVATE,
  NULL,NULL,"Console Test",NULL,NULL,
  100,45,640,200,WBENCHSCREEN
};

struct IntuitionBase *IntuitionBase;


char controls_wait_for_user(struct Window *conwin)
{
    struct MsgPort    *consoleMP        = NULL;
    struct IOStdReq   *consoleIO        = NULL;
    int                open_result      = -1;
    unsigned long      console_signal   = 0UL;
    unsigned long      break_signal     = 0UL;
    char               console_data     = '\0';
    ULONG                 received_signals = 0L;

    consoleMP = CreateMsgPort();
    if(consoleMP == NULL)
    {
        fprintf(stderr, "Error in controls_wait_for_user(), could not create message port\n");
        goto _RETURN_ERROR;
    }

    consoleIO = CreateIORequest(consoleMP, sizeof(struct IOStdReq));
    if(consoleIO == NULL)
    {
        fprintf(stderr, "Error in controls_wait_for_user(), could not create I/O request\n");
        goto _RETURN_ERROR;
    }

    consoleIO->io_Data   = conwin;
    consoleIO->io_Length = sizeof(struct Window);
    if((open_result = OpenDevice("console.device", CONU_STANDARD, (struct IORequest *)consoleIO, CONFLAG_DEFAULT)) != 0)
    {
        fprintf(stderr, "Error in controls_wait_for_user(), could not access console with error %d\n", open_result);
        goto _RETURN_ERROR;
    }
    
    while(TRUE)
    {
        consoleIO->io_Command = CMD_READ;
        consoleIO->io_Flags   = IOF_QUICK;
        consoleIO->io_Length  = 1 * sizeof(char);
        consoleIO->io_Data    = (APTR)&console_data;

        printf("Here\n");
        SendIO((struct IORequest *)consoleIO);

        received_signals = Wait((1L << consoleMP->mp_SigBit) | SIGBREAKF_CTRL_C);
        if((received_signals & SIGBREAKF_CTRL_C) == SIGBREAKF_CTRL_C)
        {
            break;
        }
        printf("character = %c\n", console_data);
    }

    goto _RETURN_OK;
    _RETURN_OK:
        // CloseDevice((struct IORequest *)consoleIO);
        DeleteIORequest(consoleIO);
        DeleteMsgPort(consoleMP);
        return '0';

    goto _RETURN_ERROR;
    _RETURN_ERROR:
        if(open_result != 0)
        {
            // CloseDevice((struct IORequest *)consoleIO);
        }
        if(consoleIO != NULL)
        {
            DeleteIORequest(consoleIO);
        }
        if(consoleMP != NULL)
        {
            DeleteMsgPort(consoleMP);
        }
        return '0';
}


int main(int argc,char *argv[])
{
  struct Window *win;

  if (IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",36)) {
    if (win = OpenWindow(&newconwin)) {
      controls_wait_for_user(win);
      CloseWindow(win);
    }
  }
  return 0;
}
phx is offline  
Old 26 August 2015, 02:22   #7
tygre
Returning fan!
 
tygre's Avatar
 
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 1,434
Thanks phx!

Actually, my real problem is: how can I hijacking "safely" the current Console? I wish I could not have to OpenDevice("console.device"... but, rather, use the one provided by the Shell?

Any idea?
tygre is offline  
Old 26 August 2015, 19:04   #8
alkis
Registered User
 
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
What are you trying to achieve?
Wouldn't something like that work:

Code:
  while(exitCondition==FALSE) {
    PollStatusFromArexx();
    PollSignal();
    if (PollKeyboard())
       do_something_with_scanf();
    Delay(10);
  }
alkis is offline  
Old 26 August 2015, 23:55   #9
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,500
When polling is an option, you could also put your current shell window from CON: into RAW: mode by sending an ACTION_SCREEN_MODE DOS-packet to your process' MsgPort. Then use WaitForChar() and Read() for reading single characters.

Refer to http://wiki.amigaos.net/wiki/AmigaDOS_Packets , section "Using Packets Directly".
phx is offline  
Old 27 August 2015, 07:05   #10
ReadOnlyCat
Code Kitten
 
Join Date: Aug 2015
Location: Montreal/Canadia
Age: 52
Posts: 1,178
Out of curiosity, for which application do you need this?

I have the feeling that there would be a simpler solution available if we knew exactly why you need the feature you are trying to implement.

Before the multitasking input manipulating feature, what is the general action you are trying to accomplish?
ReadOnlyCat is offline  
Old 06 September 2015, 03:38   #11
tygre
Returning fan!
 
tygre's Avatar
 
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 1,434
Dear all!

Thank you for your precious advice and suggestions: following the links provided here (and many other!) I managed to get something working for AmiModRadio: I have now a process that is "polling" the player through its ARexx port and that can interrupt the Wait()ing of the main process when no more modules are playing

The code is essentially in the implementation of the "player listener" process implementation and in the _interruptable_getchar(void) function

Any code review would be more than welcome as I am not sure what I was doing but it works

Cheers!
tygre is offline  
Old 11 September 2015, 05:33   #12
ReadOnlyCat
Code Kitten
 
Join Date: Aug 2015
Location: Montreal/Canadia
Age: 52
Posts: 1,178
Quote:
Originally Posted by tygre View Post
Dear all!
[...]

Any code review would be more than welcome as I am not sure what I was doing but it works

Cheers!
My, that's a lot of code to review so I'll go to the most obvious issue at a (very) quick glance:

You have plenty of these
goto label
instructions followed immediately by the corresponding label, like so:

Code:
	goto _RETURN_OK;
	_RETURN_OK:
		free(list);
		controls_set_last_message("Showed blacklisted files");
		return RETURN_OK;

	goto _RETURN_ERROR;
	_RETURN_ERROR:
What did you want to do when you wrote them?
The error labels are useful since they are used when exiting the functions upon error but the
goto
statements right before the labels essentially do nothing.
ReadOnlyCat is offline  
Old 21 December 2015, 22:01   #13
tygre
Returning fan!
 
tygre's Avatar
 
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 1,434
Hi ReadOnlyCat!

Sorry for the delay, I was not notified of your message

Thank you for your review: my idea with these gotos is to "simulate" a kind of exception mechanism: whenever something goes wrong, I jump to _RETURN_ERROR, while I use _RETURN_OK to cleanup when things went well

Any other comments is welcome!
tygre is offline  
Old 22 December 2015, 04:56   #14
ReadOnlyCat
Code Kitten
 
Join Date: Aug 2015
Location: Montreal/Canadia
Age: 52
Posts: 1,178
Hum, I understand what you are trying to achieve but there must be simpler solutions.
Moreover, by using this system even in places where that structure is not needed the code becomes harder to read.

I won't have time to give it a deeper thought for a few days but I'll try between Christmas and New Year's Eve.
ReadOnlyCat is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
Boot block examples? h0ffman Coders. General 3 04 March 2011 16:44
Advice on interrupts and jumps alexh Coders. General 11 20 May 2008 09:42
AGA programming with C examples/tutorials? Calgor Coders. General 13 04 April 2007 18:53
Amiga Workbench was not the first multitasking OS Fred the Fop Retrogaming General Discussion 26 04 January 2007 19:36
Plasma examples anyone? jobro Coders. General 5 27 November 2005 17:25

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 13:03.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.17749 seconds with 13 queries