base-4.21.0.0: Core data structures and operations
Copyright(c) Tamar Christina 2019
LicenseBSD-style (see the file libraries/base/LICENSE)
Maintainerlibraries@haskell.org
Stabilitystable
Portabilitynon-portable
Safe HaskellNone
LanguageHaskell2010

GHC.Event.Windows.FFI

Description

WinIO Windows API Foreign Function imports

Synopsis

IOCP

newtype IOCP Source #

An I/O completion port.

Constructors

IOCP HANDLE 

Instances

Instances details
Show IOCP Source # 
Instance details

Defined in GHC.Internal.Event.Windows.FFI

Eq IOCP Source # 
Instance details

Defined in GHC.Internal.Event.Windows.FFI

Methods

(==) :: IOCP -> IOCP -> Bool Source #

(/=) :: IOCP -> IOCP -> Bool Source #

Ord IOCP Source # 
Instance details

Defined in GHC.Internal.Event.Windows.FFI

type CompletionKey = ULONG_PTR Source #

newIOCP :: IO IOCP Source #

Create a new I/O completion port.

associateHandleWithIOCP :: IOCP -> HANDLE -> CompletionKey -> IO () Source #

Associate a HANDLE with an I/O completion port.

getQueuedCompletionStatusEx Source #

Arguments

:: IOCP 
-> Array OVERLAPPED_ENTRY 
-> DWORD

Timeout in milliseconds (or iNFINITE)

-> IO Int 

Note [Completion Ports] ~~~~~~~~~~~~~~~~~~~~~~~ When an I/O operation has been queued by an operation (ReadFileWriteFileetc) it is placed in a queue that the driver uses when servicing IRQs. This queue has some important properties:

  1. ) It is not an ordered queue. Requests may be performed out of order as as the OS's native I/O manager may try to re-order requests such that as few random seeks as possible are needed to complete the pending operations. As such do not assume a fixed order between something being queued and dequeued.
  2. ) Operations may skip the queue entirely. In which case they do not end in in this function. (This is an optimization flag we have turned on. See openFile.)
  3. ) Across this call the specified OVERLAPPED_ENTRY buffer MUST remain live, and the buffer for an I/O operation cannot be freed or moved until getOverlappedResult says it's done. The reason is the kernel may not have fully released the buffer, or finished writing to it when this operation returns. Failure to adhere to this will cause your IRQs to be silently dropped and your program will never receive a completion for it. This means that the OVERLAPPED buffer must also remain valid for the duration of the call and as such must be allocated on the unmanaged heap.
  4. ) When a thread calls this method it is associated with the I/O manager's worker threads pool. You should always use dedicated threads for this since the OS I/O manager will now monitor the threads. If the thread becomes blocked for whatever reason, the Haskell I/O manager will wake up another threads from it's pool to service the remaining results. A new thread will also be woken up from the pool when the previous thread is busy servicing requests and new requests have finished. For this reason the Haskell IO manager multiplexes IO operations from N haskell threads into 1 completion port, which is serviced by M native threads in an asynchronous method. This allows it to scale efficiently.

postQueuedCompletionStatus :: IOCP -> DWORD -> CompletionKey -> LPOVERLAPPED -> IO () Source #

Manually post a completion to the specified I/O port. This will wake up a thread waiting GetQueuedCompletionStatusEx.

getOverlappedResult :: HANDLE -> Ptr OVERLAPPED -> BOOL -> IO (Maybe DWORD) Source #

Get the result of a single overlap operation without the IO manager

Completion Data

data CompletionData Source #

Structure that the I/O manager uses to associate callbacks with additional payload such as their OVERLAPPED structure and Win32 handle etc. *Must* be kept in sync with that in `winio_structs.h` or horrible things happen.

We keep the handle around for the benefit of ghc-external libraries making use of the manager.

Constructors

CompletionData 

Fields

type CompletionCallback a Source #

Arguments

 = ErrCode

0 indicates success

-> DWORD

Number of bytes transferred

-> IO a 

Called when the completion is delivered.

withRequest :: Bool -> Word64 -> HANDLE -> IOCallback -> (Ptr HASKELL_OVERLAPPED -> Ptr CompletionData -> IO a) -> IO a Source #

Overlapped

data OVERLAPPED Source #

Tag type for LPOVERLAPPED.

type LPOVERLAPPED = Ptr OVERLAPPED Source #

Identifies an I/O operation. Used as the LPOVERLAPPED parameter for overlapped I/O functions (e.g. ReadFile, WSASend).

data HASKELL_OVERLAPPED Source #

Tag type for the extended version of OVERLAPPED containing some book keeping information.

type LPHASKELL_OVERLAPPED = Ptr HASKELL_OVERLAPPED Source #

Pointer to the extended HASKELL_OVERLAPPED function.

allocOverlapped Source #

Arguments

:: Word64

Offset/OffsetHigh

-> IO (Ptr HASKELL_OVERLAPPED) 

Allocate a new <http://msdn.microsoft.com/en-us/library/windows/desktop/ms684342%28v=vs.85%29.aspx OVERLAPPED> structure on the unmanaged heap. This also zeros the memory to prevent the values inside the struct to be incorrectly interpreted as data payload.

We extend the overlapped structure with some extra book keeping information such that we don't have to do a lookup on the Haskell side.

Future: We can gain some performance here by using a pool instead of calling malloc for each request. A simple block allocator would be very useful here, especially when we implement sockets support.

zeroOverlapped :: LPHASKELL_OVERLAPPED -> IO () Source #

Zero-fill an HASKELL_OVERLAPPED structure.

pokeOffsetOverlapped :: LPOVERLAPPED -> Word64 -> IO () Source #

Set the offset field in an OVERLAPPED structure.

Cancel pending I/O

cancelIoEx :: HANDLE -> LPOVERLAPPED -> IO () Source #

Cancel all pending overlapped I/O for the given file that was initiated by the current OS thread. Cancelling is just a request for cancellation and before the OVERLAPPED struct is freed we must make sure that the IRQ has been removed from the queue. See getOverlappedResult.

Monotonic time

GetTickCount

getTickCount64 :: IO Word64 Source #

Call the GetTickCount64 function, which returns a monotonic time in milliseconds.

Problems:

  • Low resolution (10 to 16 milliseconds).

http://msdn.microsoft.com/en-us/library/windows/desktop/ms724408%28v=vs.85%29.aspx

QueryPerformanceCounter

queryPerformanceCounter :: IO Int64 Source #

Call the QueryPerformanceCounter function.

Problems:

  • Might not be available on some hardware. Use queryPerformanceFrequency to test for availability before calling this function.
  • On a multiprocessor computer, may produce different results on different processors due to hardware bugs.

To get a monotonic time in seconds, divide the result of queryPerformanceCounter by that of queryPerformanceFrequency.

http://msdn.microsoft.com/en-us/library/windows/desktop/ms644904%28v=vs.85%29.aspx

queryPerformanceFrequency :: IO (Maybe Int64) Source #

Call the QueryPerformanceFrequency function. Return Nothing if the hardware does not provide a high-resolution performance counter.

http://msdn.microsoft.com/en-us/library/windows/desktop/ms644905%28v=vs.85%29.aspx

Miscellaneous