Amiga.org
Operating System Specific Discussions => Amiga OS => Amiga OS -- Development => Topic started by: kas1e on April 11, 2006, 03:59:23 PM
-
Here is example:
#include <dos/dostags.h>
#include <proto/dos.h>
#include <proto/exec.h>
struct Process *player;
__saveds void play_module(void)
{
Printf("ooooo\n");
Printf("uuuu\n");
Printf("ieeetss\n");
}
int main(void)
{
printf("first\n");
player = CreateNewProcTags(
NP_Entry, &play_module,
NP_Priority, 1,
NP_Name, "Player Process",
TAG_DONE);
printf("second\n");
Delay(200);
printf("third\n");
}
so, result:
work:programming>spawn_vbcc
first
ooooo
uuuu
ieeetss
second
third
work:programming>spawn_sasc
first
second
third
work:programming>
It looks like over vbcc it works, over sasc - not. If i add (for example) in span thread a fucntion like SystemTagList("newcli",0); over vbcc is works, over sasc - reboot with red flashing of screen.
by default i have nosmalldata and nosmallcode in sasc options. Any idea how it must be looks like ?:)
-
I'm not sure but according to AutoDocs, processes created by CreateNewProc() by default have assigned both input and output to opens of NIL:. Try adding these tags:
NP_Input,stdin,
NP_Output,stdout,
This should fix the problem with not displaying anything from the child process on SAS/C. However, I'm not sure about the hang, take a look into dos/dostags.h, maybe there are some other tags you have to use...
-
was try also this:
player = CreateNewProcTags(
NP_Entry, &play_module,
NP_Priority, 1,
NP_Name, "Player Process",
NP_Input, Input(),
NP_CloseInput, FALSE,
NP_Output, Output(),
NP_CloseOutput, FALSE,
TAG_DONE);
the same. also, why it works over vbcc, and do not works over sasc ?
-
@ kas1e
Hmmm, I've given my hints out of my memory (currently I'm not programming for Amiga). Therefore I forgot many things and now I'm not sure if this "NP_Input,stdin," (and same for output) would actualy work? Or "Input()" and "Output()" functions have to be used instead?
-
@Kas1e
"NP_Entry, &play_module"
Shouldn't that be "NP_Entry, play_module" ?
-
You must not do buffered I/O from multiple processes, dos.library filehandles are NOT semaphore protected (nor are most libnix stdio implementations). The behaviour is undefined. If you must output some debug from the sub thread, use kprintf.
Mixing dos.library and stdio I/O result in undefined behaviour.
Don't trust on priorities when doing multiprocess apps, this will break eventually. Use interprocess communcation, see IPC example (http://www.iki.fi/sintonen/src/ipc) (Note: This particular example uses 2nd LoadSeg()d function as the 2nd process. It could aswell be another function.)
-
@piru
Thanks for good answer, but question is still here:
why CreateNewProcTags do not works over sasc, and the same code works ok on vbcc ? Maybe someone have little example for sasc how it must be used ?
I do not mean with printf, any example will be good. Just spawning a new console, or write somethink to file. In other words, anythink that will show , that proccess is created and works (i mean over sasc of course).
-
@kas1e
why CreateNewProcTags do not works over sasc, and the same code works ok on vbcc ?
I guess you missed my point: CreateNewProcTags works just fine, but using Printf for output does not.
Maybe this'll explain it best:
#include <dos/dostags.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <clib/debug_protos.h>
struct Process *player;
static volatile int quit;
__saveds void play_module(void)
{
kprintf("ooooo\n");
kprintf("uuuu\n");
kprintf("ieeetss\n");
Forbid();
quit = 1;
}
int main(void)
{
kprintf("first\n");
player = CreateNewProcTags(
NP_Entry, &play_module,
NP_Priority, 1,
NP_Name, "Player Process",
TAG_DONE);
if (player)
{
kprintf("second\n");
while (!quit)
{
Delay(20);
}
kprintf("third\n");
}
return 0;
}
compile with: sc nostkchk link test.c lib lib:debug.lib
UPDATE: stack check would screw it up before, sorry for not figuring it out earlier ;-)
-
@piru
maybe it's strange, but i copy your example 1:1, and do compiling as you said 1:1 too. After running - freeze or reboot or red flashing screen.
I tryed it on winuae, but the same code over vbcc works just fine. I also try it on my a1200/060. After running nothink happenes. CPU is loaded on 100%.
maybe will be matter version of sasc which i am using. On compiling stage it sais: SAS/C amiga compiper 6.50
-
I'm using SAS/C Amiga Compiler 6.58
You could try: sc resopt link test.c lib lib:debug.lib
This should eliminate problems from some weird SCOPTS file.
-
The same .. will try to upgrade to the 6.58 right now.
-
I should prolly remind you that kprintf output is not seen normally (it's using the serial). You should probably use sashimi to grab it.
-
The same .. will try to upgrade to the 6.58 right now.
edit: but 100% of cpu load it is not normal. and it's just must do kprintfs (so be not to console), and exit. But is always in freeze state.
btw, if i will put in newproc SystemTagList("newcli",0); without any printfs/kprintfs it must spawn a shell i think ?
-
after patch to 6.55. it works, but very strange. sometimes it runs ok , sometimes not. sometimes it run ok from golded ide, sometimes not. from the shell, or from icon, or from dopus - can't run always (faulth is here).
for you it's just works always ? in the shell, from icon, etc ?
right now, i just recopy your example, go to the shell, and put your compiling string:
work:programming>sc resopt link spawn_thread.c lib lib:debug.lib
SAS/C Amiga Compiler 6.58
Copyright (c) 1988-1995 SAS Institute Inc.
Slink - Version 6.58
Copyright (c) 1988-1995 SAS Institute, Inc. All Rights Reserved.
SLINK Complete - Maximum code size = 1948 ($0000079c) bytes
Final output file size = 2540 ($000009ec) bytes
work:programming>spawn_thread
and faulth is here.
-
It was the stack check code screwing it up. nostkchk cures it.
More explanation: It would compare the stack pointer for overflow at play_module, and if the pointer was lower than the limit set at startup code, it would set up a requester and exit. However, play_module was run on context of a second process, and thus stack pointer was randomly either before or after the main task stack. This is why it failed randomly.
I've updated the code to poll some variable for termination aswell, far from perfect but at least it should never crash now.
-
@piru
thanks, with 'nostkchk' works always just fine :) also maybe you can give me a little brief about Forbid() and Permit() calls ? I understand from docs of course, that forbid() - forbid task resheduiling, and while not found Permit(); will dissallow resheduiling, but where it's necessary in real life ? i mean in all of my lame srcs i do not use Forbid/Permit, but all works ok. where it necessary really ?
-
It is necessary if you don't want to have random crashes.
For example in the edited example the Forbid() call is absolutely needed (and without matching Permit() call, even).
If there was no Forbid() the quit flag would be set to 1, and then if rescheduling would occur the main program would get to run. When the main program finishes, the shell/Workbench will free the seglist. Now imagine if the sub process would then get scheduled to run. The memory holding the seglist would be free and something else might have reused it already -> crash.
Normally Forbid() call must have a matching Permit() call, but end of process is special case, here you can do Forbid() and let process end handle it (evetually RemTask(NULL) takes care of the pending Forbid).
If you are performing operations from multiple processes, or you're scanning system lists you need to have arbitration. System lists require use of Forbid()/Permit(). Your own stuff can potentially use semaphores.