diff options
Diffstat (limited to 'qemu/roms/ipxe/src/include/ipxe/process.h')
-rw-r--r-- | qemu/roms/ipxe/src/include/ipxe/process.h | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/qemu/roms/ipxe/src/include/ipxe/process.h b/qemu/roms/ipxe/src/include/ipxe/process.h new file mode 100644 index 000000000..2c76ff260 --- /dev/null +++ b/qemu/roms/ipxe/src/include/ipxe/process.h @@ -0,0 +1,205 @@ +#ifndef _IPXE_PROCESS_H +#define _IPXE_PROCESS_H + +/** @file + * + * Processes + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <ipxe/list.h> +#include <ipxe/refcnt.h> +#include <ipxe/tables.h> + +/** A process */ +struct process { + /** List of processes */ + struct list_head list; + /** Process descriptor */ + struct process_descriptor *desc; + /** Reference counter + * + * If this process is not part of a reference-counted object, + * this field may be NULL. + */ + struct refcnt *refcnt; +}; + +/** A process descriptor */ +struct process_descriptor { + /** Offset of process within containing object */ + size_t offset; + /** + * Single-step the process + * + * This method should execute a single step of the process. + * Returning from this method is isomorphic to yielding the + * CPU to another process. + */ + void ( * step ) ( void *object ); + /** Automatically reschedule the process */ + int reschedule; +}; + +/** + * Define a process step() method + * + * @v object_type Implementing method's expected object type + * @v step Implementing method + * @ret step Process step method + */ +#define PROC_STEP( object_type, step ) \ + ( ( ( ( typeof ( step ) * ) NULL ) == \ + ( ( void ( * ) ( object_type *object ) ) NULL ) ) ? \ + ( void ( * ) ( void *object ) ) step : \ + ( void ( * ) ( void *object ) ) step ) + +/** + * Calculate offset of process within containing object + * + * @v object_type Containing object data type + * @v name Process name (i.e. field within object data type) + * @ret offset Offset of process within containing object + */ +#define process_offset( object_type, name ) \ + ( ( ( ( typeof ( ( ( object_type * ) NULL )->name ) * ) NULL ) \ + == ( ( struct process * ) NULL ) ) \ + ? offsetof ( object_type, name ) \ + : offsetof ( object_type, name ) ) + +/** + * Define a process descriptor + * + * @v object_type Containing object data type + * @v process Process name (i.e. field within object data type) + * @v step Process' step() method + * @ret desc Object interface descriptor + */ +#define PROC_DESC( object_type, process, _step ) { \ + .offset = process_offset ( object_type, process ), \ + .step = PROC_STEP ( object_type, _step ), \ + .reschedule = 1, \ + } + +/** + * Define a process descriptor for a process that runs only once + * + * @v object_type Containing object data type + * @v process Process name (i.e. field within object data type) + * @v step Process' step() method + * @ret desc Object interface descriptor + */ +#define PROC_DESC_ONCE( object_type, process, _step ) { \ + .offset = process_offset ( object_type, process ), \ + .step = PROC_STEP ( object_type, _step ), \ + .reschedule = 0, \ + } + +/** + * Define a process descriptor for a pure process + * + * A pure process is a process that does not have a containing object. + * + * @v step Process' step() method + * @ret desc Object interface descriptor + */ +#define PROC_DESC_PURE( _step ) { \ + .offset = 0, \ + .step = PROC_STEP ( struct process, _step ), \ + .reschedule = 1, \ + } + +extern void * __attribute__ (( pure )) +process_object ( struct process *process ); +extern void process_add ( struct process *process ); +extern void process_del ( struct process *process ); +extern void step ( void ); + +/** + * Initialise process without adding to process list + * + * @v process Process + * @v desc Process descriptor + * @v refcnt Containing object reference count, or NULL + */ +static inline __attribute__ (( always_inline )) void +process_init_stopped ( struct process *process, + struct process_descriptor *desc, + struct refcnt *refcnt ) { + INIT_LIST_HEAD ( &process->list ); + process->desc = desc; + process->refcnt = refcnt; +} + +/** + * Initialise process and add to process list + * + * @v process Process + * @v desc Process descriptor + * @v refcnt Containing object reference count, or NULL + */ +static inline __attribute__ (( always_inline )) void +process_init ( struct process *process, + struct process_descriptor *desc, + struct refcnt *refcnt ) { + process_init_stopped ( process, desc, refcnt ); + process_add ( process ); +} + +/** + * Check if process is running + * + * @v process Process + * @ret running Process is running + */ +static inline __attribute__ (( always_inline )) int +process_running ( struct process *process ) { + return ( ! list_empty ( &process->list ) ); +} + +/** Permanent process table */ +#define PERMANENT_PROCESSES __table ( struct process, "processes" ) + +/** + * Declare a permanent process + * + * Permanent processes will be automatically added to the process list + * at initialisation time. + */ +#define __permanent_process __table_entry ( PERMANENT_PROCESSES, 01 ) + +/** Define a permanent process + * + */ +#define PERMANENT_PROCESS( name, step ) \ +static struct process_descriptor name ## _desc = PROC_DESC_PURE ( step ); \ +struct process name __permanent_process = { \ + .list = LIST_HEAD_INIT ( name.list ), \ + .desc = & name ## _desc, \ + .refcnt = NULL, \ +}; + +/** + * Find debugging colourisation for a process + * + * @v process Process + * @ret col Debugging colourisation + * + * Use as the first argument to DBGC() or equivalent macro. + */ +#define PROC_COL( process ) process_object ( process ) + +/** printf() format string for PROC_DBG() */ +#define PROC_FMT "%p+%zx" + +/** + * printf() arguments for representing a process + * + * @v process Process + * @ret args printf() argument list corresponding to PROC_FMT + */ +#define PROC_DBG( process ) process_object ( process ), (process)->desc->offset + +#endif /* _IPXE_PROCESS_H */ |