Amiga.org

Operating System Specific Discussions => Amiga OS => Amiga OS -- Development => Topic started by: Jose on September 20, 2004, 05:20:29 PM

Title: Stupid question about if it's possible to link and create two separate executables
Post by: Jose on September 20, 2004, 05:20:29 PM
Is it possible to have two different programs recognize each others variables with linking but still be compiled to two different executables?
I know it sounds stupid but the reason is that I want a created process to be created after the main task and I want it to recognize some global variables between the two.
Now if you know another way of creating a process in
[Edit] I handled this without problems with V36 of course...
Title: Re: Stupid question about if it's possible to link and create two separate executables
Post by: Karlos on September 20, 2004, 07:14:17 PM
I don't have the documentation handy, but there must be a way to create a Process pre v36 without trying to resort to this kind of thing.

Do you absolutely need pre v36 compatibility anyway?
Title: Re: Stupid question about if it's possible to link and create two separate executables
Post by: thorrin on September 20, 2004, 08:15:18 PM
Well, Im not too good with AmigaOS, but in VxWorks you can pass messages between tasks.  A message is a type of interrupt that will 'wake up' a seperate pending task.  Im sure something like this exists in the AmigaOS.

Or if you want to do some brute force coding (which would be very bad), you could hard code a place in memory to hold the variables, but you would probably overwrite something else in the process...  ie:  there is no guarantee that some other program wouldnt be using the exact memory.

In 'C', something like this would work... say you have a variable that you want to share between the tasks, you could store that variable at some address (say 0x8000 0000). To access the var, you could do some funky pointer stuff:

    *((int*)(0x8000000)) = 5  //store 5 at 0x8000 0000 in program 1
    x = *((int*)(0x8000000))  //get what is at 0x8000 0000 in program 2

this solution is really only good for embedded programming... something where you KNOW there wont be a collision.  But it will work.  Trying this on your amiga may crash it in ways you cant imagine :-P

-Thorrin
Title: Re: Stupid question about if it's possible to link and create two separate executables
Post by: Karlos on September 20, 2004, 10:45:35 PM
@Thorrin

That type of messaging would be extremely hit and miss under AmigaOS. You aren't supposed to use any absolute address (apart from when banging hardware regusters) and sharing variables in this way would be dangerous even if you could. There is no "ownership" possible - one thread may change the variable without the other being aware right in the middle of it doing something with it.

Fortunately amigaos does allow you to create message ports that can be registered (by name) with the system to allow interprocess communication by passing (by reference) messages between ports.

Still, neither of these seem particularly relevant to Jose's problem. There must be a way to create processes in pre v36 AmigaOS without having to load a segment list. How does CreateNewProc() do it?
Title: Re: Stupid question about if it's possible to link and create two separate executables
Post by: bloodline on September 20, 2004, 11:04:53 PM
Quote

Karlos wrote:
@Thorrin

That type of messaging would be extremely hit and miss under AmigaOS. You aren't supposed to use any absolute address (apart from when banging hardware regusters) and sharing variables in this way would be dangerous even if you could. There is no "ownership" possible - one thread may change the variable without the other being aware right in the middle of it doing something with it.

Fortunately amigaos does allow you to create message ports that can be registered (by name) with the system to allow interprocess communication by passing (by reference) messages between ports.

Still, neither of these seem particularly relevant to Jose's problem. There must be a way to create processes in pre v36 AmigaOS without having to load a segment list. How does CreateNewProc() do it?


Maybe he/you could look at the AROS code :-)
Title: Re: Stupid question about if it's possible to link and create two separate executables
Post by: Argo on September 20, 2004, 11:16:48 PM
Message ports ala AREXX. Is that what you are talking about?
Couldn't you pass the variable values between programs like that. It wouldn't be sharing the same variable, just sharing the same information between programs.
Title: Re: Stupid question about if it's possible to link and create two separate executables
Post by: Karlos on September 20, 2004, 11:19:41 PM
@bloodline.

Yeah, I wish. These days I don't seem to have the time to do any real coding (all this php/mysql/javascript stuff is interesting but hardly as much fun as C++) - and when I do have time I'm usually to bloody knackered.

Having a job killed my inner child :-(
Title: Re: Stupid question about if it's possible to link and create two separate executables
Post by: Karlos on September 20, 2004, 11:28:26 PM
@Argo

Well, I was referring to exec's MsgPort/Message system. Your process can create a MsgPort and tell exec to add your new message port to its list of public ports, allowing other processes to look it up. The messages themselves are low level C structures that can be passed from one process to another process via these ports. There is no constraints on what that message can contain, so its quite a useful system. Processes can wait for messages to arrive at their ports and messages are automatically queued so that they are not lost if the process cannot process the message immediately.

A classic example is Intuition, which uses the system to send input events to the a window etc.

Arrex's ports are conceptually similar but not quite the same thing.
Title: Re: Stupid question about if it's possible to link and create two separate executables
Post by: thorrin on September 21, 2004, 12:13:03 AM
That sounds like what I was trying to describe in the VxWorks scenario.  I would imagine that all real time/multitasking operating systems have the same type of functionality.  I just didnt know what it was in amigaos.  In this case, he could create a structure as the message with the new variable values and pass THAT to the other task.

The only issue that I can think of doing it this way is if both tasks can modify variables.  You would have to have some kind of way to ensure that there aren't 2 variable change requests being sent at the same time.

And yeah, I know that the direct memory thing is BAD :-D, but it was a useful bit of info to pass on and in some cases its necessary (like you said... banging the HW)
   
-Thorrin

Quote

Karlos wrote:
@Argo

Well, I was referring to exec's MsgPort/Message system. Your process can create a MsgPort and tell exec to add your new message port to its list of public ports, allowing other processes to look it up. The messages themselves are low level C structures that can be passed from one process to another process via these ports. There is no constraints on what that message can contain, so its quite a useful system. Processes can wait for messages to arrive at their ports and messages are automatically queued so that they are not lost if the process cannot process the message immediately.

A classic example is Intuition, which uses the system to send input events to the a window etc.

Arrex's ports are conceptually similar but not quite the same thing.
 
Title: Re: Stupid question about if it's possible to link and create two separate executables
Post by: Jose on September 21, 2004, 12:06:16 PM
Hi. 8-)  Well no, I don´t absolutely need pre v36 compatibility but it would be cool to have it, it could mean when my app is done it will run on more machnines. I won't sacrifice it because of that though...
Message ports, yeah, I know. I'm currently using signals in some parts wich are faster :-) But yes, when the need is passing variables I guess sending a message would be the only way. Still it would be nice to have a process created without needing to have to load it from disk. I also found some stuff about separate compilation of two executables but with linking in some Linux discussion groups (no I'm not into Linux at all I just found that...) and though that could be another solution. But maybe that's not possible with AmigaOS. If I remember correctly with AmigaOS some locations are resolved at load time.


Anyway, what I want the created process to know about is the mainprocess's (the one that created it) task structure so that it can send it a signal. I guess I can do a FindTask(NULL) on the main process and send the result as a message to the second one, wich I'd have to locate first with FindTask (name)... I was just hoping that there would be another way...
Title: Re: Stupid question about if it's possible to link and create two separate executables
Post by: Piru on September 21, 2004, 12:41:50 PM
Quote
Is it possible to have two different programs recognize each others variables with linking but still be compiled to two different executables?
I know it sounds stupid but the reason is that I want a created process to be created after the main task and I want it to recognize some global variables between the two.

No, you need to somehow pass ptr to some structure you use to share data. Convinient and flexible way is to use messages, it allows great dynamic control of the subprocess: My IPC example (http://www.iki.fi/sintonen/src/ipc/)

Some uglier hacks use tc_UserData or pr_ExitData of the just created struct Process. If you do this, remember to enclose CreateNewProc + field poking in Forbid/Permit or else the code gets to run before you have chance to poke the ptr in.

Quote
Now if you know another way of creating a process in

The answer would be fake seglist passed to CreateProc.

Something like:
Code: [Select]

#include <exec/execbase.h>
#include <dos/dos.h>

#include <proto/exec.h>
#include <proto/dos.h>

#ifdef __GNUC__
# pragma pack(2)
#endif
struct fakeseg
{
  ULONG size;
  BPTR  next;
  UWORD jmp;
  APTR  myfunc;
};
#ifdef __GNUC__
# pragma pack()
#endif

extern struct ExecBase *SysBase;

BPTR allocfakeseg(void (*func)(void))
{
  struct fakeseg *seg = AllocMem(sizeof(*seg),
                                 MEMF_PUBLIC);
  if (seg)
  {
    seg->size   = 16;
    seg->next   = 0;
    seg->jmp    = 0x4EF9;
    seg->myfunc = (APTR) func;

    if (SysBase->LibNode.lib_Version >= 37)
    {
      CacheClearE(seg, sizeof(*seg), CACRF_ClearI);
    }
    else
    {
      /* Call some asm cacheclear function that handles possible
         020/030 caches. 040+ is only supported on 2.0+. */

      /* flushcaches(); */
    }    

    return MKBADDR(&seg->next);
  }

  return 0;
}

void freefakeseg(BPTR segptr)
{
  if (segptr)
  {
    struct fakeseg *seg = (APTR) (((ULONG *) BADDR(segptr)) - 1);

    FreeMem(seg, sizeof(*seg));
  }
}

void code(void)
{
  /* ... */
}

int main(void)
{
  BPTR seg;

  seg = allocfakeseg(code);
  if (seg)
  {
    /* use seg */

    freefakeseg(seg);
  }

  return 0;
}

Obviously you still need to provide proper syncronization so that you don't call freefakeseg prematurely.
Title: Re: Stupid question about if it's possible to link and create two separate executables
Post by: bloodline on September 21, 2004, 02:25:02 PM
Just a quick question José...

Why don't you allocate some memory (making sure to set the MEMF_PUBLIC flag ;-)), then reserve the first word for use as a flag.
Then pass a pointer to this memory block to your child task.
Now both programs can use the memory block, but make sure you check the first word before you read/write the memory block.

If you want to read/write the memory block, read the first word, if it contains -1 (or something) then the memory block is in use, and you can't use it.

If it reads 0, then set the first word to -1 and use the memory block... once you finish using it write 0 to the first word.

That should do what you want to do.
Title: Re: Stupid question about if it's possible to link and create two separate executables
Post by: Karlos on September 21, 2004, 04:44:43 PM
@bloodline

Slight variation on that - simply create a struct that has all your shared globals in it and pass a pointer to that structure (via a Message) to the other task.

That struct could also contain a SignalSemaphore as part of its definition which would be used solve the concurrency issue.
Title: Re: Stupid question about if it's possible to link and create two separate executables
Post by: bloodline on September 21, 2004, 04:50:05 PM
Quote

Karlos wrote:
@bloodline

Slight variation on that - simply create a struct that has all your shared globals in it and pass a pointer to that structure (via a Message) to the other task.

That struct could also contain a SignalSemaphore as part of its definition which would be used solve the concurrency issue.


Hmmm... yeah that makes more sense... I got to stop thinking ASM :-)
Title: Re: Stupid question about if it's possible to link and create two separate executables
Post by: thorrin on September 21, 2004, 05:44:53 PM
Dern, y'all are going to make me get an AmigaOne and start coding up some stuff...  This all sounds like good fun.

-Thorrin
Title: Re: Stupid question about if it's possible to link and create two separate executables
Post by: Jose on September 21, 2004, 11:01:46 PM
Thx all for your time, I decided I'll just go for the messages and ports solution... Semaphores won't be needed because the data won't be dynamic.
Title: Re: Stupid question about if it's possible to link and create two separate executables
Post by: bloodline on September 22, 2004, 01:58:24 PM
Quote

Karlos wrote:
@bloodline

Slight variation on that - simply create a struct that has all your shared globals in it and pass a pointer to that structure (via a Message) to the other task.

That struct could also contain a SignalSemaphore as part of its definition which would be used solve the concurrency issue.


One point though, can you allocate the struct in memory that has an MEMF_PUBLIC flag? (I'm having visions of some pointer magic here :-P)

With my method, the memory is labled as sharable, so even if memory protection were implemented (no I'm not going to start a debate on that topic :-D), it would still work... but if you use a struct then the memory would be allocated from the Program's heap and would be protected against another task.

Title: Re: Stupid question about if it's possible to link and create two separate executables
Post by: bloodline on September 22, 2004, 02:01:27 PM
Quote

thorrin wrote:
Dern, y'all are going to make me get an AmigaOne and start coding up some stuff...  This all sounds like good fun.

-Thorrin


Why not just download AROS and Code up some stuff right now!?!?! :lol:
Title: Re: Stupid question about if it's possible to link and create two separate executables
Post by: Jose on September 23, 2004, 01:02:28 PM
@bloodline

"One point though, can you allocate the struct in memory that has an MEMF_PUBLIC flag? (I'm having visions of some pointer magic here )....
 "... but if you use a struct then the memory would be allocated from the Program's heap and would be protected against another task."

Code: [Select]
struct OurStructure *OurMessage

OurMessage = (struct OurStructure*)AllocMem (sizeof(OurStructure), MEMF_PUBLIC|MEMF_CLEAR))
/* Initialize the structure after*/
Title: Re: Stupid question about if it's possible to link and create two separate executables
Post by: bloodline on September 23, 2004, 02:10:42 PM
Quote

Jose wrote:
@bloodline

"One point though, can you allocate the struct in memory that has an MEMF_PUBLIC flag? (I'm having visions of some pointer magic here )....
 "... but if you use a struct then the memory would be allocated from the Program's heap and would be protected against another task."

Code: [Select]
struct OurStructure *OurMessage

OurMessage = (struct OurStructure*)AllocMem (sizeof(OurStructure), MEMF_PUBLIC|MEMF_CLEAR))
/* Initialize the structure after*/


Ahhh pointer magic then :-) :pint:
Title: Re: Stupid question about if it's possible to link and create two separate executables
Post by: Piru on September 23, 2004, 02:53:30 PM
Quote
Code: [Select]
struct OurStructure *OurMessage

OurMessage = (struct OurStructure*)AllocMem (sizeof(OurStructure), MEMF_PUBLIC|MEMF_CLEAR))
/* Initialize the structure after*/

That would be either:
Code: [Select]

struct OurStructure *OurMessage;

OurMessage = (struct OurStructure *) AllocMem(sizeof(struct OurStructure), MEMF_PUBLIC|MEMF_CLEAR);

or:
Code: [Select]

struct OurStructure *OurMessage;

OurMessage = (struct OurStructure *) AllocMem(sizeof(*OurMessage), MEMF_PUBLIC|MEMF_CLEAR);
Title: Re: Stupid question about if it's possible to link and create two separate executables
Post by: Karlos on September 23, 2004, 04:18:52 PM
Quote

bloodline wrote:

Ahhh pointer magic then :-) :pint:


Well, this is only C after all. You have 2 options

1) allocate memory using exec or clib (the former is better for OS specific stuff of course)

2) create a constructor / destructor function pair, that in turn use (1) in order to achieve their task.

Either way, it always comes down to pointer magic. C++ offers various other approaches, except that too is also pointer magic, you just don't necessarily have to cast manually (depending on how you allocated your object,that is).

Let's face it, any raw memory handling for object memory will always involve some form of explicit/implicit pointer conversion.
Title: Re: Stupid question about if it's possible to link and create two separate executables
Post by: PiR on September 23, 2004, 06:12:22 PM
Quote
Let's face it, any raw memory handling for object memory will always involve some form of explicit/implicit pointer conversion.

Yes. No more miserable excuses. We're all grown men here, we can stand the truth. ;-)
Title: Re: Stupid question about if it's possible to link and create two separate executables
Post by: Karlos on September 23, 2004, 07:57:18 PM
*drunkenly staggers, points and shouts angrily*

Truth? You can't handle the truth!

*collapses in stupor at keyboard and writes the next generation memory allocation mechanism accidently from a series of random face+keyboard interactions...*
Title: Re: Stupid question about if it's possible to link and create two separate executables
Post by: bloodline on September 24, 2004, 09:16:53 AM
It's a curious thought that AOS doesn't have any memory sharing functions... with semaphor protection etc... I suppose one could use "files" on the Ram: device... but that sounds too Unixie to me :-D
Title: Re: Stupid question about if it's possible to link and create two separate executables
Post by: Karlos on September 24, 2004, 11:42:48 AM
@bloodline

It isn't really needed as you can semaphore protect anything you choose to, the SignalSemaphore is completely general purpose. Hence you can allocate some memory and simply make sure you appropriately use the semaphore before accessing it. SignalSemaphores are quite flexible, you can get exclusive and read only (shared) locks etc.

Title: Re: Stupid question about if it's possible to link and create two separate executables
Post by: PiR on October 06, 2004, 06:23:00 PM
Hi

I dig through all the documentation I could find and I give up.
Can anyone (yes, Piru, I'm talking to you...) be so kind and explain me, why in all examples with fakeSegList there is always '16' put in the 'size' field?
To be more curious - why there is anything at all, if you are not allowed to call UnloadSeg() for it anyway...

And one last related thing - what is the interpretation of this size in this DOS/BCPL world? Number of bytes/words/longs/doubles/lines/pages/magic_number_that_is_always_set_to_16_regardles_of_anything?

Code: [Select]

struct fakeseg
{
  ULONG size;
  BPTR  next;
  UWORD jmp;
  APTR  myfunc;
};


From my calculations sizeof( struct fakeseg ) = 14.
But hmmm... If I remember correctly BCPL uses only longs. So mayby sizeof() must always be multiplication of 4? So, to be precise it should be rather:

Code: [Select]

struct fakeseg
{
  ULONG size;
  BPTR  next;
  UWORD jmp;
  APTR  myfunc;
  UWORD _filler;
};


On the other hand if it's not used for anything, why to bother and initiate it at all?

Correct me if I'm wrong.

Thanks.
Title: Re: Stupid question about if it's possible to link and create two separate executables
Post by: Speelgoedmannetje on October 06, 2004, 07:06:18 PM
:nervous: pointers :nervous:

no really, I think you need to redesign your programme
use multithreading (sweet Amiga :-))

and make use of MUTEXES
Title: Re: Stupid question about if it's possible to link and create two separate executables
Post by: Piru on October 06, 2004, 07:47:57 PM
@PiR

Try to put 6 bytes of data (yes 'size' and 'next' are not really part of it) to a segment. Then load the segment with LoadSeg. Segment 'size' will be 16.

Basically the size of the data is padded to multiple of longwords (4), and thus to stay consistent the fake segment size is also 16 and not 14.

So in a sense using _filler like that is not a bad idea, it makes the sizeof() correct, too. It is not strictly speaking needed, though.

Quote
On the other hand if it's not used for anything, why to bother and initiate it at all?

Some applications scan the seglists, and if the fields would not be set properly these apps could crash.
Title: Re: Stupid question about if it's possible to link and create two separate executables
Post by: Noster on November 10, 2004, 08:21:32 AM
Hi

@Jose

Haven't read the whole thread (no time :-() but you can use a really simple fake seglist instead of a real seglist in CreateProc():

Think you have a pointer to the function that should be the entrypoint into your new process:

void (*pfv)(void);

Now you can simply get a BPTR to this function using:

BPTR sl;

sl = MKBADDR(pfv) - 1;

Now you can create your process:

struct MsgPort *mp;

mp = CreateProc ("ChildProc", DEFAULT_PRI, sl, DEFAULT_STACK);

The entry address of a function used this way must be aligned to a longword address, under SAS/C the first function of an object module can be considered appropriate for this conversion; it may have to be declared with the __saveds keyword.

This is documented in "The Amiga Guru Book" from Ralph Babel and I have tested it under every AmigaOS 1.3+. I think you will get problems if the code should be converted to OS 4.0 :-)

Noster