4.7 KiB
PAL
Overview
The modules in PAL is splited into 3 layers:
- c_pal_ll - contains platform abstractions with no additional dependencies on other modules outside of c_pal_ll itself : arithmetic, gballoc, interlocked, sync, threadapi, platform, socket_handle, srw_lock, sysinfo, timer, uuid
- c_pal/common - contains utilities needed by the PAL, which may depend on the c_pal_ll : call_once, containing_record, interlocked_hl, lazy_init, log_critical_and_terminate, ps_util, refcount, s_list, sm
- c_pal - contains remaining platform abstractions, which may depend on the c_pal_ll and/or common utilities : asynchronous_socket, execution_engine, file, pipe, threadpool, string_utils
Each of these APIs have:
- an interface header (for example execution_engine.h)
- specific platform implementations (for example execution_engine_win32.c)
Project structure:
- interfaces - project that contains all the interface headers (no specific platform implementations exist in this folder/project)
- win32 - project that contains concrete Windows implementations for the components (execution_engine_win32.c, ...).
For design details of specific platforms see the design document for that platform.
Execution engine
typedef struct EXECUTION_ENGINE* EXECUTION_ENGINE_HANDLE;
MOCKABLE_FUNCTION(, EXECUTION_ENGINE_HANDLE, execution_engine_create, void*, execution_engine_parameters);
MOCKABLE_FUNCTION(, void, execution_engine_dec_ref, EXECUTION_ENGINE_HANDLE, execution_engine);
MOCKABLE_FUNCTION(, void, execution_engine_inc_ref, EXECUTION_ENGINE_HANDLE, execution_engine);
The execution engine component is the context needed for instantiating any of the other 3 components (threadpool, asynchronous socket APIS, asynchronous file APIS). For example on Windows it wraps a PTP_POOL. Thus in order to instantiate a thread pool component, first an execution engine object needs to be created.
The reason the execution engine exists is in order to be able to have multiple threadpool API/asynchronous API objects created based on the same execution engine (in Windows terms using only one PTP_POOL one can create as many instances of asynchronous socket objects as needed).
When an execution engine is created is receives a void*
argument which contains platform specific arguments.
For example for Windows it is desired to specify the min and max number of threads for the PTP_POOL being created. Thus for Windows a platform specific argument structure is used:
typedef struct EXECUTION_ENGINE_PARAMETERS_TAG
{
uint32_t min_thread_count;
uint32_t max_thread_count;
} EXECUTION_ENGINE_PARAMETERS;
Threadpool API
The thread pool API object allows scheduling work items in a threadpool.
It provides the following functionality (exact APIs will be defined in module requirements):
- create - create the threadpool object based on an execution engine
- destroy - frees resources associated with the threadpool object
- open_async - opens the threadpool object (work can be scheduled on it after open completes)
- close - closes the theadpool object (all work has either been executed or cancelled after close completes)
- schedule_work - schedules a work item to be executed in the threadpool
Asynchronous socket API
The asynchronous socket API object allows sending/receiving asynchronously over a socket using platform specific asynchronous APIs.
It provides the following functionality (exact APIs will be defined in module requirements):
- create - create the asynchronous socket object based on an execution engine
- destroy - frees resources associated with the asynchronous socket
- open_async - opens the asynchronous socket object (send/receives can be performed when open is complete)
- close - closes the asynchronous socket
- send_async - sends a number of byte buffers asynchronously
- on_receive - a number of byte buffers have been received asynchronously
- on_error - an error has occured and user needs to handle it
Asynchronous file API
The asynchronous file API object allows writing/reading asynchronously from a file using platform specific asynchronous APIs.
It provides the following functionality (exact APIs will be defined in module requirements):
- create - create the asynchronous file object based on an execution engine
- destroy - frees resources associated with the asynchronous file object
- open_async - opens the asynchronous file object (reads/writes can be performed when open is complete)
- close - closes the asynchronous file object
- write_async - writes a byte buffer asynchronously as a given position in the file
- read_async - reads a byte buffer asynchronously as a given position in the file
- on_error - an error has occured and user needs to handle it