home *** CD-ROM | disk | FTP | other *** search
/ Shareware Supreme Volume 6 #1 / swsii.zip / swsii / 215 / DDJWIN.ZIP / FORTAN.ASC < prev    next >
Text File  |  1993-08-31  |  21KB  |  705 lines

  1. _MULTITASKING FORTRAN AND WINDOWS NT_
  2. by Shakar Vaidyanathan
  3.  
  4.  
  5. [LISTING ONE]
  6.  
  7.  interface to integer*4 function CreateEvent
  8. +    [stdcall, alias: '_CreateEventA@16']
  9. +    (security, reset, init_state, string)
  10.    integer*4 security [value]
  11.    Logical*4 reset [value]
  12.    Logical*4 init_state [value]
  13.    integer*4 string [value]
  14.  end
  15.  
  16.  interface to integer*4 function CreateMutex
  17. +    [stdcall, alias: '_CreateMutexA@12']
  18. +    (security, owner, string)
  19.     integer*4 security [value]
  20.     Logical*4 owner [value]
  21.     integer*4 string [value]
  22.   end
  23.  
  24.   interface to logical*4 function CreateProcess
  25.  +    [stdcall, alias: '_CreateProcessA@40']
  26.  +    (lpApplicationName, lpCommandLine, lpProcessAttributes,
  27.  +    lpThreadAttributes, bInheritHandles, dwCreationFlags,
  28.  +    lpEnvironment, lpCurrentDirectory, lpStartupInfo,
  29.  +    lpProcessInformation)
  30.     integer*4 lpApplicationName [value]
  31.     integer*4 lpCommandLine [value]
  32.     integer*4 lpProcessAttributes [value]
  33.     integer*4 lpThreadAttributes [value]
  34.     logical*4 bInheritHandles [value]
  35.     integer*4 dwCreationFlags [value]
  36.     integer*4 lpEnvironment [value]
  37.     integer*4 lpCurrentDirectory [value]
  38.     integer*4 lpStartupInfo [value]
  39.     integer*4 lpProcessInformation [value]
  40.   end
  41.     
  42.   interface to integer*4 function CreateSemaphore
  43.  +    [stdcall, alias: '_CreateSemaphoreA@16']
  44.  +    (security, InitialCount, MaxCount, string)
  45.     integer*4 security [value]
  46.     integer*4 InitialCount [value]
  47.     integer*4 MaxCount [value]
  48.     integer*4 string [value]
  49.   end
  50.  
  51.   interface to integer*4 function CreateThread 
  52.  +    [stdcall, alias: '_CreateThread@24']
  53.  +    (security, stack, thread_func, 
  54.  +    argument, flags, thread_id)
  55.     integer*4 security [value]
  56.     integer*4 stack [value]
  57.     integer*4 thread_func [value]
  58.     integer*4 argument [reference]
  59.     integer*4 flags [value]
  60.     integer*4 thread_id [reference]
  61.   end
  62.  
  63.   interface to subroutine DeleteCriticalSection
  64.  +    [stdcall, alias: '_DeleteCriticalSection@4'] (object)
  65.     integer*4 object [value]
  66.   end
  67.  
  68.   interface to logical*4 function DuplicateHandle
  69.  +    [stdcall, alias: '_DuplicateHandle@28'] 
  70.  +    (hSourceProcessHandle, hSourceHandle,
  71.  +     hTargetProcessHandle, lpTargetHandle,
  72.  +     dwDesiredAccess, bInheritHandle, dwOptions)
  73.     integer*4 hSourceProcessHandle [value]
  74.     integer*4 hSourceHandle [value]
  75.     integer*4 hTargetProcessHandle [value]
  76.     integer*4 lpTargetHandle [reference]
  77.     integer*4 dwDesiredAccess [value]
  78.     logical*4 bInheritHandle [value]
  79.     integer*4 dwOptions [value]
  80.   end
  81.  
  82.   interface to subroutine EnterCriticalSection
  83.  +    [stdcall, alias: '_EnterCriticalSection@4'] (object)
  84.     integer*4 object [value]
  85.   end
  86.  
  87.   interface to subroutine ExitProcess
  88.  +    [stdcall, alias: '_ExitProcess@4'] (ExitCode)
  89.     integer*4 ExitCode [value]
  90.   end
  91.  
  92.   interface to subroutine ExitThread
  93.  +    [stdcall, alias: '_ExitThread@4'] (ExitCode)
  94.     integer*4 ExitCode [value]
  95.   end
  96.  
  97.   interface to integer*4 function GetCurrentProcess
  98.  +   [stdcall, alias: '_GetCurrentProcess@0'] ()
  99.   end
  100.  
  101.   interface to integer*4 function GetCurrentProcessId
  102.  +   [stdcall, alias: '_GetCurrentProcessId@0'] ()
  103.   end
  104.  
  105.   interface to integer*4 function GetCurrentThread
  106.  +   [stdcall, alias: '_GetCurrentThread@0'] ()
  107.   end
  108.  
  109.   interface to integer*4 function GetCurrentThreadId
  110.  +   [stdcall, alias: '_GetCurrentThreadId@0'] ()
  111.   end
  112.  
  113.   interface to logical*4 function GetExitCodeProcess
  114.  +   [stdcall, alias: '_GetExitCodeProcess@8'] 
  115.  +   (hProcess, lpExitCode)
  116.     integer*4 hProcess [value]
  117.     integer*4 lpExitCode [reference]
  118.   end
  119.  
  120.   interface to logical*4 function GetExitCodeThread
  121.  +   [stdcall, alias: '_GetExitCodeThread@8'] 
  122.  +   (hThread, lpExitCode)
  123.     integer*4 hThread [value]
  124.     integer*4 lpExitCode [reference]
  125.   end
  126.  
  127.   interface to integer*4 function GetLastError
  128.  +    [stdcall, alias: '_GetLastError@0'] ()
  129.   end
  130.  
  131.   interface to integer*4 function GetThreadPriority
  132.  +   [stdcall, alias: '_GetThreadPriority@4'] (hThread)
  133.     integer*4 hThread [value]
  134.   end
  135.  
  136.   interface to logical*4 function GetThreadSelectorEntry
  137.  +   [stdcall, alias: '_GetThreadSelectorEntry@12'] 
  138.  +   (hThread, dwSelector, lpSelectorEntry)
  139.     integer*4 hThread [value]
  140.     integer*4 dwSelector [value]
  141.     integer*4 lpSelectorEntry [value]    ! Pass loc of the struct
  142.   end
  143.  
  144.   interface to subroutine InitializeCriticalSection
  145.  +    [stdcall, alias: '_InitializeCriticalSection@4'] (object)
  146.     integer*4 object [value]
  147.   end
  148.  
  149.   interface to subroutine LeaveCriticalSection
  150.  +    [stdcall, alias: '_LeaveCriticalSection@4'] (object)
  151.     integer*4 object [value]
  152.   end
  153.  
  154.   interface to integer*4 function OpenEvent
  155.  +     [stdcall, alias: '_OpenEventA@12']
  156.  +     (dwDesiredAccess, bInheritHandle, lpName)
  157.     integer*4 dwDesiredAccess [value]
  158.     logical*4 bInheritHandle [value]
  159.     integer*4 lpName [value]
  160.   end
  161.  
  162.   interface to integer*4 function PulseEvent
  163.  +    [stdcall, alias: '_PulseEvent@4'] (hEvent)
  164.     integer*4 hEvent [value]
  165.   end
  166.  
  167.   interface to Logical*4 function ReleaseMutex
  168.  +    [stdcall, alias: '_ReleaseMutex@4'] (handle)
  169.     integer*4 handle [value]
  170.   end
  171.  
  172.   interface to Logical*4 function ReleaseSemaphore
  173.  +    [stdcall, alias: '_ReleaseSemaphore@12'] 
  174.  +    (handle, ReleaseCount, LpPreviousCount)
  175.     integer*4 handle [value]
  176.     integer*4 ReleaseCount [value]
  177.     integer*4 LpPreviousCount [reference]
  178.   end
  179.  
  180.   interface to integer*4 function ResumeThread
  181.  +   [stdcall, alias: '_ResumeThread@4'] (hThread)
  182.     integer*4 hThread [value]
  183.   end
  184.  
  185.   interface to integer*4 function SetEvent
  186.  +    [stdcall, alias: '_SetEvent@4'] (handle)
  187.     integer*4 handle [value]
  188.   end
  189.  
  190.   interface to subroutine SetLastError
  191.  +    [stdcall, alias: '_SetLastError@4'] (dwErrorCode)
  192.     integer*4 dwErrorCode [value]
  193.   end
  194.  
  195.   interface to logical*4 function SetThreadPriority
  196.  +   [stdcall, alias: '_SetThreadPriority@8'](hThread, nPriority)
  197.     integer*4 hThread [value]
  198.     integer*4 nPriority [value]
  199.   end
  200.  
  201.   interface to integer*4 function SuspendThread
  202.  +   [stdcall, alias: '_SuspendThread@4'] (hThread)
  203.     integer*4 hThread [value]
  204.   end
  205.  
  206.   interface to logical*4 function TerminateProcess
  207.  +   [stdcall, alias: '_TerminateProcess@8'] 
  208.  +   (hProcess, uExitCode)
  209.     integer*4 hProcess [value]
  210.     integer*4 uExitCode [value]
  211.   end
  212.  
  213.   interface to logical*4 function TerminateThread
  214.  +   [stdcall, alias: '_TerminateThread@8'] 
  215.  +   (hThread, dwExitCode)
  216.     integer*4 hThread [value]
  217.     integer*4 dwExitCode [value]
  218.   end
  219.  
  220.   interface to integer*4 function TlsAlloc
  221.  +   [stdcall, alias: '_TlsAlloc@0'] ()
  222.   end
  223.  
  224.   interface to logical*4 function TlsFree
  225.  +   [stdcall, alias: '_TlsFree@4'] (dwTlsIndex)
  226.     integer*4 dwTlsIndex [value]
  227.   end
  228.  
  229.   interface to integer*4 function TlsGetValue
  230.  +   [stdcall, alias: '_TlsGetValue@4'] (dwTlsIndex)
  231.     integer*4 dwTlsIndex [value]
  232.   end
  233.  
  234.   interface to logical*4 function TlsSetValue
  235.  +   [stdcall, alias: '_TlsSetValue@8'] (dwTlsIndex, lpTlsVal)
  236.     integer*4 dwTlsIndex [value]
  237.     integer*4 lpTlsVal [value]
  238.   end
  239.  
  240.   interface to integer*4 function WaitForMultipleObjects
  241.  +    [stdcall, alias: '_WaitForMultipleObjects@16']
  242.  +    (Count, LpHandles, WaitAll, Mseconds)
  243.     integer*4 Count [value]
  244.     integer*4 LpHandles [reference]
  245.     logical*4 WaitAll [value]
  246.     integer*4 Mseconds [value]
  247.   end
  248.  
  249.   interface to integer*4 function WaitForSingleObject
  250.  +    [stdcall, alias: '_WaitForSingleObject@8']
  251.  +    (handle, Mseconds)
  252.     integer*4 handle [value]
  253.     integer*4 Mseconds [value]
  254.   end
  255.  
  256.  
  257.  
  258. [LISTING TWO]
  259.  
  260. PARAMETER (MAX_THREADS = 50)
  261. PARAMETER (WAIT_INFINITE = -1)
  262. PARAMETER (STANDARD_RIGHTS_REQUIRED = #F0000)
  263. PARAMETER (SYNCHRONIZE = #100000)
  264.  
  265. STRUCTURE /PROCESS_INFORMATION/
  266.     integer*4 hProcess 
  267.     integer*4 hThread
  268.     integer*4 dwProcessId
  269.     integer*4 dwThreadId
  270. END STRUCTURE
  271.  
  272. STRUCTURE /RTL_CRITICAL_SECTION_DEBUG/
  273.     integer*4 Type 
  274.     integer*4 CreatorBackTraceIndex
  275.     integer*4 Address
  276.     integer*4 ProcessLocksList
  277.     integer*4 EntryCount
  278.     integer*4 ContentionCount
  279.     integer*4 Depth
  280.     integer*4 OwnerBackTrace(5)
  281. END STRUCTURE
  282.  
  283. STRUCTURE /RTL_CRITICAL_SECTION/
  284.     integer*4 Address 
  285.     integer*4 LockCount
  286.     integer*4 RecursionCount
  287.     integer*4 OwningThread
  288.     integer*4 LockSemaphore
  289.     integer*4 Reserved
  290. END STRUCTURE
  291.  
  292. STRUCTURE /SECURITY_ATTRIBUTES/
  293.     integer*4 nLength 
  294.     integer*4 lpSecurityDescriptor
  295.     logical*4 bInheritHandle
  296. END STRUCTURE
  297.  
  298. STRUCTURE /STARTUPINFO/
  299.     integer*4 cb
  300.     integer*4 lpReserved
  301.     integer*4 lpDesktop
  302.     integer*4 lpTitle
  303.     integer*4 dwX
  304.     integer*4 dwY
  305.     integer*4 dwXSize
  306.     integer*4 dwYSize
  307.     integer*4 dwXCountChars
  308.     integer*4 dwYCountChars
  309.     integer*4 dwFillAttribute
  310.     integer*4 dwFlags
  311.     integer*2 wShowWindow
  312.     integer*2 cbReserved2
  313.     integer*4 lpReserved2
  314. END STRUCTURE
  315.  
  316.  
  317.  
  318. [LISTING THREE]
  319.  
  320. Program to demonstrate thread creation and critical section object
  321.       include 'mt.fi'
  322.  
  323. Thread function as a subroutine
  324.       subroutine ThreadFunc (param)
  325.       include 'mt.fd'
  326.       integer*4 param, result
  327.       record /RTL_CRITICAL_SECTION/ GlobalCriticalSection
  328.       record /RTL_CRITICAL_SECTION_DEBUG/ AuxCriticalSection
  329.       common result, GlobalCriticalSection 
  330.  
  331. Critical section region begins...
  332.       Call EnterCriticalSection ( loc(GlobalCriticalSection))
  333.           result = param + result
  334.  
  335. Critical section region ends...
  336.       Call LeaveCriticalSection ( loc(GlobalCriticalSection))
  337.       Call ExitThread(0) 
  338.       return
  339.       end
  340.  
  341. Main program begins here
  342.       program test
  343.       include 'mt.fd'
  344.       external ThreadFunc
  345.       integer*4 ThreadHandle(MAX_THREADS), inarray(MAX_THREADS)
  346.       integer*4 CreateThread, threadId
  347.       integer*4 waitResult, WaitForMultipleObjects
  348.       integer*4 loop, result
  349.       record /RTL_CRITICAL_SECTION/ GlobalCriticalSection
  350.       record /RTL_CRITICAL_SECTION_DEBUG/ AuxCriticalSection
  351.       common result, GlobalCriticalSection 
  352.  
  353. Creating the cyclic structure for the critical section object
  354.       GlobalCriticalSection.Address = loc(AuxCriticalSection)
  355.       AuxCriticalSection.Address = loc(GlobalCriticalSection)
  356.  
  357.       result = 0
  358.  
  359. Initializing critical section...
  360.       Call InitializeCriticalSection(loc(GlobalCriticalSection))
  361.  
  362.       do loop = 1, MAX_THREADS
  363.          inarray(loop)= loop
  364.          write(*, '(1x, A, I3)') 'Creating Thread # ', loop
  365.          ThreadHandle(loop) = CreateThread( 0, 0, loc(ThreadFunc), inarray(loop), 0, threadId) 
  366.       end do
  367.  
  368.       write(*,*) 'Waiting for all the threads to complete ...'
  369.       waitResult = WaitForMultipleObjects
  370.      +   (MAX_THREADS, ThreadHandle, .TRUE. , WAIT_INFINITE) 
  371.       write(*, '(1x, A, I6, A, I10)' ) 
  372.      +   'The sum of the first ', MAX_THREADS,' #s is ', result
  373.       end
  374.  
  375.  
  376. [LISTING FOUR]
  377.  
  378. Program to demostrate the semaphore and mutual exclusion objects
  379.       include 'mt.fi'
  380.  
  381. The thread function begins here
  382.       subroutine ThreadFunc (param)
  383.       include 'mt.fd'
  384.       integer*4 param, waitResult, WaitForSingleObject
  385.       integer*4 ThreadCounter
  386.       integer*4 result, hMutex, hSemaphore, PreviousCount
  387.       logical*4 release, ReleaseMutex, ReleaseSemaphore
  388.       common result, hMutex, hSemaphore, ThreadCounter
  389.  
  390. Mutual exclusion region begins here
  391.       waitResult = WaitForSingleObject(hMutex, WAIT_INFINITE) 
  392.  
  393. Modifying the global variables 
  394.           result = param + result
  395.           ThreadCounter = ThreadCounter + 1
  396.  
  397. Release the sempahore if this is the last thread
  398.           if (ThreadCounter .EQ. MAX_THREADS) 
  399.      +         release = ReleaseSemaphore(hSemaphore, 1, PreviousCount)
  400.  
  401. Mutual exclusion region ends here
  402.       release = ReleaseMutex(hMutex)
  403.       return
  404.       end
  405.  
  406. Main program begins here
  407.       program test
  408.       include 'mt.fd'
  409.       external ThreadFunc
  410.       integer*4 ThreadHandle, threadId 
  411.       integer*4 CreateSemaphore, CreateThread, CreateMutex
  412.       integer*4 waitResult, WaitForSingleObject
  413.       integer*4 loop
  414.       integer*4 result, hMutex, hSemaphore, ThreadCounter
  415.       integer*4 inarray
  416.       dimension inarray(MAX_THREADS)
  417.       common result, hMutex, hSemaphore, ThreadCounter
  418.  
  419. Initializing the global variables
  420.       ThreadCounter = 0
  421.       result = 0
  422.       hMutex = CreateMutex(0, .FALSE. , 0)
  423.       hSemaphore = CreateSemaphore(0, 0, 1, 0)
  424.  
  425.       do loop = 1, MAX_THREADS
  426.          inarray(loop)= loop
  427.          write(*,*) "Generating Thread #", loop
  428.          ThreadHandle = CreateThread( 0, 0, loc(ThreadFunc), 
  429.      +         inarray(loop), 0, threadId) 
  430.       end do
  431.  
  432.       write(*,*) 'Waiting for the semaphore release...'
  433.       waitResult = WaitForSingleObject(hSemaphore, WAIT_INFINITE) 
  434.       write(*, '(1x, A, I4, A, I8)')
  435.      +    'The sum of the first ', MAX_THREADS,' #s is', result
  436.       end
  437.  
  438.  
  439.  
  440. [LISTING FIVE]
  441.  
  442. Parent Program (process) passing names of event objects to child process
  443.       include 'mt.fi'
  444.  
  445.       program Parent
  446.       include 'mt.fd'
  447.       logical*4 procHandle, CreateProcess
  448.       integer*4 CreateEvent, hReadEvent, hWriteEvent, SetEvent
  449.       integer*4 waitResult, WaitForSingleObject
  450.       character*255 buffer
  451.       character*10 strReadEvent, strWriteEvent, FileName
  452.  
  453.       record /PROCESS_INFORMATION/ pi
  454.       record /STARTUPINFO/ si
  455.  
  456. Initializing the strings
  457.       strReadEvent = 'ReadEvent '
  458.       strWriteEvent = 'WriteEvent '
  459.       FileName = ' file.out '
  460.       buffer = "child "//strReadEvent//strWriteEvent//FileName//" "C
  461.       strReadEvent(10:10) = char(0)
  462.       strWriteEvent(10:10) = char(0)
  463.  
  464. Initializing the STARTUPINFO structure
  465.       si.cb = 56             ! sizeof (STARTUPINFO)
  466.       si.lpReserved = 0
  467.       si.lpDeskTop = 0
  468.       si.lpTitle = 0
  469.       si.dwFlags = 0
  470.       si.cbReserved2 = 0
  471.       si.lpReserved2 = 0
  472.   
  473. Creating Read and Write Event objects
  474.       hReadEvent = CreateEvent(0, .FALSE., .FALSE., loc(strReadEvent))       
  475.       hWriteEvent = CreateEvent(0, .FALSE., .FALSE.,loc(strWriteEvent))       
  476.  
  477. Spawning the child prcoess
  478.       procHandle=CreateProcess(0,loc(buffer),0,0,.TRUE.,0,0,0,loc(si),loc(pi))
  479.  
  480. Providing a question for the child
  481.       open (10, file= FileName)
  482.       write(10, '(A)') "What issue of Dr. Dobb's is this?"
  483.       close (10)
  484.  
  485.       write(*,*) 'Providing the green signal for child to continue...'
  486.       waitResult = SetEvent(hWriteEvent)
  487.       write(*,*) 'Waiting for the child to answer the question - '
  488.       waitResult = WaitForSingleObject (hReadEvent, WAIT_INFINITE)
  489.  
  490. Writing the reply from the child on to the screen
  491.       open (10, file= FileName)
  492.       read(10, '(A)') buffer
  493.       close (10)
  494.       write(*,*) buffer 
  495.       end
  496.  
  497.  
  498.  
  499.  
  500. [LISTING SIX]
  501.  
  502. Child program (process) accepting named objects from the parent
  503.       include 'mt.fi'
  504.  
  505.       program ChildProcess 
  506.       include 'mt.fd'
  507.  
  508.       character*255 buffer
  509.       character*100 filename, strReadEvent, strWriteEvent
  510.       integer*4 hReadEvent, hWriteEvent, OpenEvent, SetEvent
  511.       integer*2 status
  512.       integer*4 EVENT_ALL_ACCESS
  513.       integer*4 waitResult, WaitForSingleObject
  514.  
  515. Retrieving the first command line parameter which is the name of the ReadEvent
  516.       Call Getarg (1, buffer, status)
  517.       strReadEvent(1:status) = buffer(1:status)
  518.       status = status+1
  519.       strReadEvent(status:status) = char(0) ! to make it a C string
  520.  
  521. Retrieving the second command line parameter which is the name of the WriteEvent
  522.       Call Getarg (2, buffer, status)
  523.       strWriteEvent(1:status) = buffer(1:status)
  524.       status = status+1
  525.       strWriteEvent(status:status) = char(0) ! to make it a C string
  526.  
  527. Setting the access privilege for the child
  528.       EVENT_ALL_ACCESS = IOR (STANDARD_RIGHTS_REQUIRED, SYNCHRONIZE)
  529.       EVENT_ALL_ACCESS = IOR (EVENT_ALL_ACCESS, #3)
  530.  
  531. Opening the handles for the event objects passed from the parent as named objects
  532.       hReadEvent=OpenEvent(EVENT_ALL_ACCESS, .FALSE.,  loc(strReadEvent))
  533.       hWriteEvent=OpenEvent(EVENT_ALL_ACCESS, .FALSE., loc(strWriteEvent))
  534.  
  535. Wait until the parent signals the WriteEvent
  536.       waitResult = WaitForSingleObject(hWriteEvent, WAIT_INFINITE) 
  537.     
  538. Retrieve the file name which is the third argument
  539.       Call Getarg (3, buffer, status)
  540.       filename (1:status) = buffer(1:status)
  541.  
  542. Read the parent's question and then reply
  543.       open (11, file= filename, mode ='readwrite')
  544.       read(11, '(A)') buffer
  545.       print *, buffer
  546.       rewind 11 
  547.       write(11, '(A)') 'September 1993 issue'
  548.       close (11) 
  549.  
  550. Signal the parent to continue
  551.       waitResult = SetEvent(hReadEvent) 
  552.       end
  553.  
  554.  
  555. [LISTING SEVEN]
  556.  
  557. A fragment of the parent program 
  558.  
  559.  ...
  560.  
  561. Initialization of Security attributes for Read and Write Events
  562.       record /SECURITY_ATTRIBUTES/ saR
  563.       record /SECURITY_ATTRIBUTES/ saW
  564.  
  565.       saR.nLength = 12
  566.       saR.lpSecurityDescriptor = 0
  567.       saR.bInheritHandle = .TRUE.
  568.  
  569.       saW.nLength = 12
  570.       saW.lpSecurityDescriptor = 0
  571.       saW.bInheritHandle = .TRUE.
  572.  
  573. Creating events whose handles can be inherited
  574.       hReadEvent = CreateEvent(loc(saR), .FALSE., .FALSE., 0)
  575.       hWriteEvent = CreateEvent(loc(saW), .FALSE., .FALSE., 0)
  576.  ...
  577. -----------------------------------------------------------------------------
  578. A fragment of the child program. Retrieve the handle to Read and Write 
  579. Events from the command line using Getarg, and assign them to integer 
  580. variables through Internal Read
  581.       CALL GETARG(1, buffer, status)
  582.       read(buffer(1:status), '(i4)') hReadEvent
  583.       CALL GETARG(2, buffer, status)
  584.       read(buffer(1:status), '(i4)') hWriteEvent
  585.  
  586.       waitResult = WaitForSingleObject(hWriteEvent, WAIT_INFINITE) 
  587.   ...
  588.  
  589.  
  590.  
  591. Example 1: (a) Prototyping CreateThread; (b) first argument to CreateThread is a structure prototyped in winbase.h; (c) implenting the structure using STRUCTURE/END STRUCTURE
  592.  
  593. (a)
  594.  
  595.     HANDLE WINAPI CreateThread (
  596.         LP_SECURITY_ATTRIBUTES lpThreadAttributes,
  597.         DWORD  dwStackSize,
  598.         LPTHREAD_START_ROUTINE  lpStartAddress,
  599.         LPVOID  lpParameter,
  600.         DWORD  dwCreationFlags,
  601.         LPDWORD  lpThreadId
  602.         );
  603.  
  604.  
  605. (b)
  606.  
  607.     typedef struct _SECURITY_ATTRIBUTES {
  608.         DWORD nLength;
  609.         LPVOID lpSecurityDescriptor;
  610.         BOOL bInheritHandle;
  611.     } SECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;
  612.  
  613.  
  614. (c)
  615.     STRUCTURE /SECURITY_ATTRIBUTES/
  616.         integer*4 length
  617.         integer*4 lpSecurityDescriptor
  618.         logical*4 bInheritHandle
  619.     END STRUCTURE
  620.  
  621.  
  622. Example 2:
  623.  
  624. (a)
  625.  
  626.  
  627. typedef struct _RTL_CRITICAL_SECTION_DEBUG {
  628.         WORD   Type;
  629.         WORD   CreatorBackTraceIndex;
  630.         struct _RTL_CRITICAL_SECTION *CriticalSection;
  631.         LIST_ENTRY ProcessLocksList;
  632.         DWORD EntryCount;
  633.         DWORD ContentionCount;
  634.         DWORD Depth;
  635.         PVOID OwnerBackTrace[ 5 ];
  636. } RTL_CRITICAL_SECTION_DEBUG, *PRTL_CRITICAL_SECTION_DEBUG;
  637.  
  638. typedef struct _RTL_CRITICAL_SECTION {
  639.         PRTL_CRITICAL_SECTION_DEBUG DebugInfo;
  640.         LONG LockCount;
  641.         LONG RecursionCount;
  642.         HANDLE OwningThread;        // from the thread's ClientId->UniqueThread
  643.         HANDLE LockSemaphore;
  644.         DWORD Reserved;
  645. } RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION;
  646.  
  647.  
  648.  
  649. (b)
  650.  
  651. STRUCTURE /RTL_CRITICAL_SECTION_DEBUG/
  652.     integer*4 Type 
  653.     integer*4 CreatorBackTraceIndex
  654.     integer*4 Address
  655.     integer*4 ProcessLocksList
  656.     integer*4 EntryCount
  657.     integer*4 ContentionCount
  658.     integer*4 Depth
  659.     integer*4 OwnerBackTrace(5)
  660. END STRUCTURE
  661.  
  662. STRUCTURE /RTL_CRITICAL_SECTION/
  663.     integer*4 Address 
  664.     integer*4 LockCount
  665.     integer*4 RecursionCount
  666.     integer*4 OwningThread
  667.     integer*4 LockSemaphore
  668.     integer*4 Reserved
  669. END STRUCTURE
  670. record /RTL_CRITICAL_SECTION/ GlobalCriticalSection
  671. record /RTL_CRITICAL_SECTION_DEBUG/ AuxCriticalSection
  672.  
  673. GlobalCriticalSection.Address = loc(AuxCriticalSection)
  674. AuxCriticalSection.Address = loc(GlobalCriticalSection)
  675.  
  676.  
  677. Example 3:
  678.  
  679.     BOOL WINAPI CreateProcessA(
  680.             LPCSTR lpApplicationName,
  681.             LPCSTR lpCommandLine,
  682.             LPSECURITY_ATTRIBUTES lpProcessAttributes,
  683.             LPSECURITY_ATTRIBUTES lpThreadAttributes,
  684.             BOOL bInheritHandles,
  685.             DWORD dwCreationFlags,
  686.             LPVOID lpEnvironment,
  687.             LPSTR lpCurrentDirectory,
  688.             LPSTARTUPINFOA lpStartupInfo,
  689.             LPPROCESS_INFORMATION lpProcessInformation
  690.     );
  691.  
  692.  
  693. Figure 1: Interface statement for CreateThread
  694.  
  695. interface to integer*4 function CreateThread [stdcall, alias: '_CreateThread@24']
  696. +   (security, stack, thread_func, arguments, flags, thread_id)
  697.    integer*4  security, stack     [value]
  698.    integer*4  thread_func [value] ! loc(thread_func) is passed by value
  699.    integer*4  arguments   [reference]
  700.    integer*4  flags       [value]
  701.    integer*4  thread_id   [reference]
  702.  end
  703.  
  704.  
  705.