Amiga.org

Operating System Specific Discussions => Amiga OS => Amiga OS -- Development => Topic started by: Jose on August 07, 2007, 04:33:14 PM

Title: Fake seglist in C...
Post by: Jose on August 07, 2007, 04:33:14 PM
From the CreateProc() autodoc:
...

If you wish to fake a seglist (that will never
    have DOS UnLoadSeg() called on it), use this code:

                DS.L    0   ;Align to longword
                DC.L    16  ;Segment "length" (faked)
                DC.L    0   ;Pointer to next segment
                ...start of code...


Anyone knows how to do this in C without having an array of LONGs with a jmp instruction in start of code (wich would be kind of unecessary and less performant) ?
Title: Re: Fake seglist in C...
Post by: Jose on August 07, 2007, 05:24:47 PM
[EDIT]
Wanted to mean "jmp instruction in start of code" not goto int or something... :roll:
You guys are getting tired of this {bleep} arent' you ? 8-)
Title: Re: Fake seglist in C...
Post by: golem on August 07, 2007, 05:31:09 PM
Jose
Why do you want to fake a seglist?
Are you cracking some code or something?
Title: Re: Fake seglist in C...
Post by: Thomas on August 07, 2007, 06:00:33 PM
@golem: no cracking, just run a subroutine of your program (instead of an externally loaded program) as a seperate thread.

@Jose: the opcode for JMP is 0x4EF9. Here is an example: http://thomas-rapp.homepage.t-online.de/examples/multi13.c

But please note that this is Kickstart 1.3 and below style of programming. Starting with Kickstart 2.0 you can use CreateNewProc with NP_Entry and don't need to fake anythimg. The same example for Kick 2.0+: http://thomas-rapp.homepage.t-online.de/examples/multi.c

An important note when working with multiple threads is that ANSI runtime routines, especially buffered I/O (printf etc.) are not thread-safe and can give various strange results. You should use the AmigaDOS equivalents (e.g. Printf with a capital "P") instead.

Bye,
Thomas
Title: Re: Fake seglist in C...
Post by: Jose on August 08, 2007, 02:43:27 PM
@golem

Just wanting to make a piece of code 1.3 compatible:)

@Thomas

That will do :) I know I should use CreateNewProc, it's just that that was the only function call preventing 1.3 compatibility, I'll probably make two versions of the final file...

:pint:
Title: Re: Fake seglist in C...
Post by: Jose on August 08, 2007, 02:49:03 PM
BTW, doesn't the main process port need to be in the public list for the subtask to be able to find it with FindPort ?
I prefer to send an ini messsage directly to the child's process MsgPort, no need to search for the parents port:)
Title: Re: Fake seglist in C...
Post by: mgerics on August 08, 2007, 03:41:23 PM
Does anyone else here think there isn't anything about the Amiga that Thomas doesn't know ??!??

I would like to personally thank him for his kind sharing of knowledge without any condescending tones. His advice is always spot on.
Title: Re: Fake seglist in C...
Post by: Piru on August 08, 2007, 03:50:31 PM
http://www.iki.fi/sintonen/src/ipc/ (http://www.iki.fi/sintonen/src/ipc/) has some small IPC example. It's rather easy to mess up subprocessing stuff, say for example have race conditions or cases where resources are not released. This IPC example shows one way of handling such things in a reliable way.

Note: This code is OS2++, but it could easily be 1.3 compatible.
Title: Re: Fake seglist in C...
Post by: Piru on August 08, 2007, 03:53:51 PM
@Thomas

Your code has a bug, it doesn't clear instruction cache for the jmp instruction. Add
CacheClearE(&segl->jump, 6, CACRF_ClearI); after the jmp has been poked.
[EDIT] Ahh, but this is KS 1.x example... Ok, that won't work. Forget that one.. :-) [/EDIT]

[EDIT2] Here's a KS 1.x compatible cache clear routine:
Code: [Select]

        include "exec/execbase.i"
        include "lvo/exec.i"

MyCacheClearU
        movem.l d0-d1/a0-a1/a6,-(sp)
        pea     (.cleanexit,pc)
        move.l  (4).w,a6
        cmp.w   #37,(LIB_VERSION,a6)
        blo.b   .manualclear
        jmp     (_LVOCacheClearU,a6)
.cleanexit
        movem.l (sp)+,d0-d1/a0-a1/a6
        rts
.manualclear
        move.l  a5,-(sp)
        lea     (.cacheclrsv,pc),a5
        jsr     (_LVOSupervisor,a6)
        move.l  (sp)+,a5
        rts
.cacheclrsv
        btst    #AFB_68020,(AttnFlags+1,a6)
        beq.b   .nocache
        btst    #AFB_68040,(AttnFlags+1,a6)
        beq.b   .is020or030
        ; 040/060
        cpusha  bc
        cinva   bc
        nop
        rte
.is020or030
        movec   cacr,d0
        or.w    #CACRF_ClearI!CACRF_ClearD,d0
        movec   d0,cacr
.nocache
        rte

[/EDIT2]

Also, Wait()ing for signal clears it. Thus it's possible that the subprocess never sees the SIGBREAKF_CTRL_C.

Relying on some Delay() + subprocessing cleaning up in the meanwhile is a bit bad coding style, especially if it ends up doing RemTask() which can potentially lock the system.

Quote
An important note when working with multiple threads is that ANSI runtime routines, especially buffered I/O (printf etc.) are not thread-safe and can give various strange results. You should use the AmigaDOS equivalents (e.g. Printf with a capital "P") instead.

Actually, many AmigaDOS functions aren't thread safe either, especially buffered I/O ones.
Title: Re: Fake seglist in C...
Post by: Piru on August 08, 2007, 04:02:37 PM
Quote
BTW, doesn't the main process port need to be in the public list for the subtask to be able to find it with FindPort ?

It does, and it is. amiga.lib CreatePort() routine does it, if you give it the port name.
Title: Re: Fake seglist in C...
Post by: Jose on August 09, 2007, 07:53:58 PM
"It does, and it is. amiga.lib CreatePort() routine does it, if you give it the port name."

Yap, I was just wanted to mean that if one uses the subprocess message port to send the ini message the main process port doesn't need to public.

Anyway, I think I just wanted to know how I could do it, now that I know I don't have the patience to support 1.3:)
Title: Re: Fake seglist in C...
Post by: Jose on August 09, 2007, 07:55:26 PM
@mgeric
In no particular order, Thomas, Piru and Karlos are the biggest contributers to this place. Haven't seen karlos here lately though...
Title: Re: Fake seglist in C...
Post by: Jose on August 09, 2007, 08:31:49 PM
@Piru

Why does it need to clear the cache ? It's not using selfmodified code and the code is already in memory so the cache data should be valid. (?)
Title: Re: Fake seglist in C...
Post by: Piru on August 09, 2007, 08:37:21 PM
@Jose
Quote
Why does it need to clear the cache ? It's not using selfmodified code and the code is already in memory so the cache data should be valid. (?)

It's building code to memory. Since it's impossible to know if this particular memory area might already be in instruction cache - containing some other, earlier instructions - it is necessary to clear the cache at least for this area.

From exec.doc:
Quote
Code: [Select]
Some examples of when the cache needs clearing:
   Self modifying code
   Building Jump tables
   Run-time code patches
   Relocating code for use at different addresses.
   Loading code from disk

Note that loading code from disk with LoadSeg() doesn't require separate cache clearing, it handles caches already.
Title: Re: Fake seglist in C...
Post by: nyteschayde on March 07, 2013, 06:04:46 AM
This thread is years old but I have a question or two. So if I understand all of this, there are at least two different ways to run some code in the background. One is using Tasks (ala CreateTask) and another is using processes using CreateProc. Tasks cannot access any file resources and probably has some other limitations as well. Processes can, it seems, but are more difficult to create and use.

I am still trying to understand MsgPort usage well as well. So, looking at includes and autodocs it seems like a Task struct has a tc_UserData value. If you use something like CreateProc or CreateNewProcTags how can you pass data using tc_userData? Possibly the answer is you can't.

Let me retry this question (sorry; I'm trying to understand as I type this), is it possible to pass arguments to your user defined function that gets executed via CreateProc or CreateNewProcTags?

If you can get access to the Task (through FindTask(NULL) or something like it) you may be able to use tc_userData but I don't know how to set this before the user function executes when using Processes.

Otherwise it seems like one might want to use a MsgPort to send the parameters to the user defined function. If so, and I am guessing here, would one's user defined function immediately set up a MsgPort and wait for messages from the creator of the Process bearing the parameters before continuing on to it's real purpose? Is there a better way?
Title: Re: Fake seglist in C...
Post by: nyteschayde on March 07, 2013, 09:45:21 AM
*BUMP*

Hoping Karlos, Piru or Thomas see this. :)
Title: Re: Fake seglist in C...
Post by: bloodline on March 07, 2013, 10:29:34 AM
Quote from: nyteschayde;728478
*BUMP*

Hoping Karlos, Piru or Thomas see this. :)
Piru chooses not to frequent our shores any more :(
Title: Re: Fake seglist in C...
Post by: nyteschayde on March 07, 2013, 10:54:29 AM
Quote from: bloodline;728481
Piru chooses not to frequent our shores any more :(


That's disheartening to hear. Guess I missed why. Do you know the answer to the question?
Title: Re: Fake seglist in C...
Post by: bloodline on March 07, 2013, 11:16:04 AM
Quote from: nyteschayde;728483
That's disheartening to hear. Guess I missed why. Do you know the answer to the question?
I can't see clearly what you are trying to achieve, from your question it looks like you are trying to pass arguments/data to the newly started task...
Title: Re: Fake seglist in C...
Post by: nyteschayde on March 07, 2013, 08:25:53 PM
That is correct. If I want to pass parameters to the function that executes inside a Process created by CreateProc or CreateNewProcTags, how would I do that without referencing global variables?

Is a MsgPort the best way? If so, how would I do that?
Title: Re: Fake seglist in C...
Post by: Thomas on March 07, 2013, 09:18:21 PM
The process stucture contains a message port (pr_MsgPort) which can be used for sending an initial message. Check how the startup code for Workbench programs receives the WBStartup message, that's just the same.

But be warned: this port can be used only in the initialisation phase of your new process. Once you want to use DOS functions, you must leave this port alone because DOS uses it for its communication.

I could make an example tomorrow if I find some spare time.
Title: Re: Fake seglist in C...
Post by: Joloo on March 07, 2013, 09:37:43 PM
Quote from: nyteschayde;728526
Is a MsgPort the best way? If so, how would I do that?


Maybe this (http://www.amimedic.de/php/getit.php?what=4) old example helps you out. If not, wait for Thomas code snippet.
Title: Re: Fake seglist in C...
Post by: nyteschayde on March 08, 2013, 12:45:07 AM
Thanks Thomas. An example would be really helpful given I am still not entirely confident using MsgPorts. Also it seems that the process kicks off right away so how do you get it to wait for the parameters via the MsgPort?

It's amazing that you guys are still knowledgeable with this stuff. I just wish there was proper documentation around. I got my first Amiga in 89 but my programming skills back then weren't anything to write home about (I was like 12 years old). Now that I program for a living professionally I wanted to tinker with some C code on the Amiga and do some fun stuff. Turns out even with the Dev CD 2.1 and related online docs things aren't always clear.

EDIT: If I had to guess it would be some code that Waited for a message at the beginning of the function that gets called by the Process. That being said, how do you reference that MsgPort in order to wait for data? All seems very confusing. If there was like a GetCurrentMsgPort() or equivalent I could see it working. On that note, also, can you use FindTask(NULL) to get a Task struct or are Procs and Tasks just that fundamentally different?
Title: Re: Fake seglist in C...
Post by: nyteschayde on March 08, 2013, 03:29:40 AM
Quote from: Joloo;728532
Maybe this (http://www.amimedic.de/php/getit.php?what=4) old example helps you out. If not, wait for Thomas code snippet.


Thanks to you too Joloo. I'll look at what you sent as well.
Title: Re: Fake seglist in C...
Post by: nyteschayde on March 08, 2013, 04:41:38 AM
Wow! I just found out that CubicIDE is now selling for like $30 USD. I can't believe it. When I first purchased it, it was ludicrously expensive. I may even buy another copy just to support the product!
Title: Re: Fake seglist in C...
Post by: nyteschayde on March 09, 2013, 06:01:47 AM
Thomas did you get a chance to write a sample? Also would you like me to take this offline given your email address is posted?
Title: Re: Fake seglist in C...
Post by: psxphill on March 09, 2013, 10:28:58 AM
Quote from: Thomas;728529
I could make an example tomorrow if I find some spare time.

I might have something from years ago that I can dig out as well.
Title: Re: Fake seglist in C...
Post by: Thomas on March 09, 2013, 01:29:43 PM
Quote from: nyteschayde;728626
Thomas did you get a chance to write a sample?


I wish you had more patience ;-)

Here are two examples, a third has yet to come:

http://thomas-rapp.homepage.t-online.de/examples/multi1.c
http://thomas-rapp.homepage.t-online.de/examples/multi2.c

The first is a simple one-shot which does its job in the background without any further communication and only replies when it is finished. The protocol used is very similar to how Workbench runs programs, sends arguments to them and waits until they are finished.

The second one is similar but it sends progress reports to the main task.

The third will be more complex. It should be a kind of server which receives commands and responds to them and stays up until it receives the stop command.

These three examples should cover most cases where you'd use multitasking in an application program.



Quote
Also would you like me to take this offline given your email address is posted?


As you can see from the first page of this thread, I am not all knowing. So it's better to stay here and give others the opportunity to correct me.
Title: Re: Fake seglist in C...
Post by: nyteschayde on March 09, 2013, 07:48:27 PM
I apologize for rushing you. I just excited and driven when I am consumed with a programming task sometimes. Most people just tell me to wait patiently but I agree that I shouldn't have to make you ask. :-\ I am very grateful for your time however. Now I can't wait to get home to my computer. I look forward to your third example as well. Again, thanks.
Title: Re: Fake seglist in C...
Post by: Thomas on March 10, 2013, 02:16:51 PM
Here is example three:

http://thomas-rapp.homepage.t-online.de/examples/multi3.c
Title: Re: Fake seglist in C...
Post by: nyteschayde on March 10, 2013, 07:33:20 PM
All of this is incredibly helpful. Thank you so much for your time. It showed me that, yes, you can use FindTask(NULL) with processes. It also showed me that, as I had wondered, there is a wait to stop the flow until the message comes through the port. It's a roundabout way to get things done compared to modern programming but it clearly works. Thanks again!
Title: Re: Fake seglist in C...
Post by: Karlos on March 11, 2013, 09:40:45 AM
Quote from: nyteschayde;728748
All of this is incredibly helpful. Thank you so much for your time. It showed me that, yes, you can use FindTask(NULL) with processes. It also showed me that, as I had wondered, there is a wait to stop the flow until the message comes through the port. It's a roundabout way to get things done compared to modern programming but it clearly works. Thanks again!


Hey, just saw this thread :)

Yes, FindTask(NULL) works since an exec.library struct Task forms the beginning part of your typical dos.library struct Process.

I wrote a C++ java-esque Thread/Runnable class system based around Process, but it's not great from an AmigaOS style compliance perspective. Also, it proved impossible to port to OS4 since as the native gcc is compiled with the single thread model. Works fine in the old 2.95.3 with threadsafe.lib on 68K/OS3 however.

I'm sure it is full of bad stuff though.
Title: Re: Fake seglist in C...
Post by: nyteschayde on March 11, 2013, 05:50:38 PM
Karol's, I'd love to see it if you have it still. Hope all has been treating you well.