Subject: Re: On the subtleties of using _beginthread to implement fork
From: [email-masked] (Chris Faylor)

13 Nov 1997 21:39:15 -0800
Message-ID: <[email-masked]>
References: <[email-masked]>
Reply-To: [email-masked]
To: [email-masked]

Wow.  You've convinced me.  Anyone who understands GlobalAlloc and
can toss around terms like "disguised sibling" obviously knows what
they're taking about.

Here's my start at a new fork implementation:

    static _USERENTRY fork2(void *);
    int fork()
    {
	_beginthread(fork2, 4096, NULL);
	return 0;
    }
    static _USERENTRY fork2(void *nada)
    {
	copy_stack_from_parent();
	set_new_process_id();
	reset_process_start_time();
	copy_heap();
	reset_heap_pointer();
	copy_globals();
	copy_statics();
	set_new_data_segment_ptr();
	copy_fds();
	isolate_scheduling_from_parent();
	isolate_signals_from_parent();
	clear_pending_alarms();
	isolate_interval_timers_from_parent();
	clear_interval_timers();
	set_stack_pointer_from_parent();	// never returns
    }

There are still a few trivial functions left unimplemented, but, as I'm
very busy right now, I'll leave them to the other CYGWIN gurus to write.

In article <[email-masked]>,  <[email-masked]> wrote:
>Some beginning programmer wrote to me that _beginthread was not suitable
>for a fork() implementation because it  supposedly uses the `same data
>segment' as its parent process.  Without discussing the subtleties of
>calling GlobalAlloc(), or even its disguised sibling, malloc(), I present
>a description of _beginthread():
>
>
>#include <process.h>
>unsigned long _beginthread(_USERENTRY (*start_address)(void *), unsigned
>stack_size, void *arglist)
>
>Description
>
>Starts execution of a new thread.
>
>Note:	The start_address must be declared to be _USERENTRY. 
>
>The _beginthread function creates and starts a new thread. The thread
>starts execution at start_address. 
>
>The size of its stack in bytes is stack_size; the stack is allocated by
>the operating system after the stack size is rounded up to the next
>multiple of 4096. The thread is passed arglist as its only parameter; it
>can be NULL, but must be present. The thread terminates by simply
>returning, or by calling _endthread.
>
>Either this function or _beginthreadNT must be used instead of the
>operating system thread-creation API function because _beginthread and
>_beginthreadNT perform initialization required for correct operation of
>the run-time library functions.
>
>This function is available only in the multithread libraries.
>
>Return Value
>
>_beginthread returns the handle of the new thread. 
>On error, the function returns -1, and the global variable errno is set to
>one of the following values:
>
>EAGAIN	Too many threads
>EINVAL	Invalid request
-- 
http://www.bbc.com/	[email-masked]			"Strange how unreal
VMS=>UNIX Solutions	Boston Business Computing	 the real can be."
-
For help on using this list (especially unsubscribing), send a message to
"[email-masked]" with one line of text: "help".