summaryrefslogtreecommitdiffstats
path: root/private/crt32/startup/thread.c
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/crt32/startup/thread.c
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/crt32/startup/thread.c')
-rw-r--r--private/crt32/startup/thread.c254
1 files changed, 254 insertions, 0 deletions
diff --git a/private/crt32/startup/thread.c b/private/crt32/startup/thread.c
new file mode 100644
index 000000000..5878eecc7
--- /dev/null
+++ b/private/crt32/startup/thread.c
@@ -0,0 +1,254 @@
+#ifdef MTHREAD
+
+
+/***
+*thread.c - Being and end a thread
+*
+* Copyright (c) 1989-1993, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* This source contains the _beginthread() and _endthread()
+* routines which are used to start and terminate a thread.
+*
+*Revision History:
+* 05-09-90 JCR Translated from ASM to C
+* 07-25-90 SBM Removed '32' from API names
+* 10-08-90 GJF New-style function declarators.
+* 10-09-90 GJF Thread ids are of type unsigned long.
+* 10-19-90 GJF Added code to set _stkhqq properly in stub().
+* 12-04-90 SRW Changed to include <oscalls.h> instead of <doscalls.h>
+* 12-06-90 SRW Added _CRUISER_ and _WIN32 conditionals.
+* 06-03-91 GJF Win32 version [_WIN32_].
+* 07-18-91 GJF Fixed many silly errors [_WIN32_].
+* 08-19-91 GJF Allow for newly created thread terminating before
+* _beginthread returns
+* 09-30-91 GJF Add per-thread initialization and termination calls
+* for floating point.
+* 01-18-92 GJF Revised try - except statement.
+* 02-25-92 GJF Initialize _holdrand field to 1.
+* 09-30-92 SRW Add WINAPI keyword to _threadstart routine
+* 10-30-92 GJF Error ret for CreateThread is 0 (NULL), not -1.
+* 02-13-93 GJF Revised to use TLS API. Also, purged Cruiser support.
+* 03-26-93 GJF Fixed horribly embarrassing bug: ptd->pxcptacttab
+* must be initialized to _XcptActTab!
+* 04-27-93 GJF Removed support for _RT_STACK, _RT_INTDIV,
+* _RT_INVALDISP and _RT_NONCONT.
+* 12-14-93 SKS Free up per-thread data using a call to _freeptd()
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <oscalls.h>
+#include <internal.h>
+#include <os2dll.h>
+#include <msdos.h>
+#include <malloc.h>
+#include <process.h>
+#include <rterr.h>
+
+/*
+ * Startup code for new thread.
+ */
+static unsigned long WINAPI _threadstart(void *);
+
+/*
+ * useful type for initialization and termination declarations
+ */
+typedef void (_CRTAPI1 *PF)(void);
+
+/*
+ * declare pointers to per-thread FP initialization and termination routines
+ */
+PF _FPmtinit;
+PF _FPmtterm;
+
+
+/***
+*_beginthread() - Create a child thread
+*
+*Purpose:
+* Create a child thread.
+*
+*Entry:
+* initialcode = pointer to thread's startup code address
+* stacksize = size of stack
+* argument = argument to be passed to new thread
+*
+*Exit:
+* success = handle for new thread if successful
+*
+* failure = (unsigned long) -1L in case of error, errno and _doserrno
+* are set
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+unsigned long _CRTAPI1 _beginthread (
+ void (_CRTAPI1 * initialcode) (void *),
+ unsigned stacksize,
+ void * argument
+ )
+{
+ _ptiddata ptd; /* pointer to per-thread data */
+ unsigned long thdl; /* thread handle */
+
+ /*
+ * Allocate and initialize a per-thread data structure for the to-
+ * be-created thread.
+ */
+ if ( (ptd = calloc(1, sizeof(struct _tiddata))) == NULL )
+ goto error_return;
+
+ ptd->_initaddr = (void *) initialcode;
+ ptd->_initarg = argument;
+ ptd->_holdrand = 1L;
+ ptd->_pxcptacttab = (void *)_XcptActTab;
+
+ /*
+ * Create the new thread. Bring it up in a suspended state so that
+ * the _thandle and _tid fields are filled in before execution
+ * starts.
+ */
+ if ( (ptd->_thandle = thdl = (unsigned long)
+ CreateThread( NULL,
+ stacksize,
+ _threadstart,
+ (LPVOID)ptd,
+ CREATE_SUSPENDED,
+ (LPDWORD)&(ptd->_tid) ))
+ == 0L )
+ goto error_return;
+
+ /*
+ * Start the new thread executing
+ */
+ if ( ResumeThread( (HANDLE)thdl ) == (DWORD)(-1L) )
+ goto error_return;
+
+ /*
+ * Good return
+ */
+ return(thdl);
+
+ /*
+ * Error return
+ */
+error_return:
+ /***
+ *** MAP ERROR CODE!
+ ***/
+ return((unsigned long)-1L);
+}
+
+
+/***
+*_threadstart() - New thread begins here
+*
+*Purpose:
+* The new thread begins execution here. This routine, in turn,
+* passes control to the user's code.
+*
+*Entry:
+* void *ptd = pointer to _tiddata structure for this thread
+*
+*Exit:
+* Never returns - terminates thread!
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+static unsigned long WINAPI _threadstart (
+ void * ptd
+ )
+{
+ /*
+ * Stash the pointer to the per-thread data stucture in TLS
+ */
+ if ( !TlsSetValue(__tlsindex, ptd) )
+ _amsg_exit(_RT_THREAD);
+
+ /*
+ * Call fp initialization, if necessary
+ */
+ if ( _FPmtinit != NULL )
+ (*_FPmtinit)();
+
+ /*
+ * Guard call to user code with a _try - _except statement to
+ * implement runtime errors and signal support
+ */
+ try {
+ ( (void(_CRTAPI1 *)(void *))(((_ptiddata)ptd)->_initaddr) )
+ ( ((_ptiddata)ptd)->_initarg );
+
+ _endthread();
+ }
+ except ( _XcptFilter(GetExceptionCode(), GetExceptionInformation()) )
+ {
+ /*
+ * Should never reach here
+ */
+ _exit( GetExceptionCode() );
+
+ } /* end of _try - _except */
+
+ /*
+ * Never executed!
+ */
+ return(0L);
+}
+
+
+/***
+*_endthread() - Terminate the calling thread
+*
+*Purpose:
+*
+*Entry:
+* void
+*
+*Exit:
+* Never returns!
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+void _CRTAPI1 _endthread (
+ void
+ )
+{
+ _ptiddata ptd; /* pointer to thread's _tiddata struct */
+
+ /*
+ * Call fp termination, if necessary
+ */
+ if ( _FPmtterm != NULL )
+ (*_FPmtterm)();
+
+ if ( (ptd = _getptd()) == NULL )
+ _amsg_exit(_RT_THREAD);
+
+ /*
+ * Close the thread handle (if there was one)
+ */
+ if ( ptd->_thandle != (unsigned long)(-1L) )
+ (void) CloseHandle( (HANDLE)(ptd->_thandle) );
+
+ /*
+ * Free up the _tiddata structure & its subordinate buffers
+ * _freeptd() will also clear the value for this thread
+ * of the TLS variable __tlsindex.
+ */
+ _freeptd(ptd);
+
+ /*
+ * Terminate the thread
+ */
+ ExitThread(0);
+
+}
+
+#endif /* MTHREAD */