[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: (another) problem with mntlib41 tfork() function



>Hi!

Hi, too!

> It was quite often mentioned that the mintlibs tfork() function shouldn't
>be regarded as anything more than a hack until MiNT gets a real vfork() call,
>so I know I should use it with caution, but today I've strumbled into a
>really severe problem when writing a multi-threaded smtp sendmail clone.
>
> It goes like this: Each time a thread is started, memory is allocated from
>the calling process via pexec(5) to create a new basepage. Since this base-
>page isn't immediately started, the memory seems to be assigned to the
>calling process. This one of course forgets the adress of the threads basepage
>as soon as the tfork() call is left.
>
> So the thread comes up, works a bit and goes down again, leaving the basepage
>memory assigned to the caller, who doesn't know about this and therefore won't
>free it. To be more precicly: Each thread costs me 16K (memprot) which are lost
>forever.
[...]
>Mightn't it be a good idea to perhaps add some Pexec() mode which does
>the same as the thread code from the library, but really assigns all child
>memory to the child, so Pterm() can free it?

Please try the following patch to MiNT 1.09:

*** o:\dosmem.c	Wed Aug 18 20:16:18 1993
--- dosmem.c	Mon Dec  6 21:32:34 1993
***************
*** 586,605 ****
--- 586,616 ----
  	 * if we didn't call fork_proc then we're overlaying.
  	 * NOTE: after this call, we may not be able to access the
  	 * original address space that the Pexec was taking place in
  	 * (if this is an overlaid Pexec, we just freed that memory).
  	 */
  		(void)exec_region(p, base, thread);
  		attach_region(p, env);
  		attach_region(p, base);
  		if (text) attach_region(p, text);

+ 		if ( mode == 104 )
+ 		{
+ 		/*
+ 		* Cause basepage and environment to be owned *only* by the
+ 		* child, not by both child and parent; when the child
+ 		* terminates, base and env are freed automagically...
+ 		*/
+ 			detach_region(curproc, base);
+ 			detach_region(curproc, env);
+ 		}
+
  		if (mkname) {
  	/* interesting coincidence -- if a process needs a name, it usually
  	 * needs to have its domain reset to DOM_TOS. Doing it this way
  	 * (instead of doing it in exec_region) means that Pexec(4,...)
  	 * can be used to create new threads of execution which retain
  	 * the same domain.
  	 */
  			if (!thread)
  				p->domain = DOM_TOS;
~~~~~~(snip)~~~~~~~~
This shouldn't cause any compatibilty problems, but I didn't really test
it...

> But I feel something like there isn't something like real child memory, so
>all memory the child may at any time allocate, is also shared by its parent.

I don't think so - as far as I can see, Pexec(104) "duplicates" all memory
owned by the parent _at this moment_, and any memory allocated by child or
parent after this point is owned _only_ by the allocating process.

-- 
 Martin Koehling | mk@anuurn.do.open.de | Martin_Koehling@un.maus.ruhr.de