123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- #ifndef _IPXE_PROCESS_H
- #define _IPXE_PROCESS_H
-
- /** @file
- *
- * Processes
- *
- */
-
- FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
- #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 {
- /** Process name */
- const char *name;
- /** 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 ) { \
- .name = #_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 ) { \
- .name = #_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 ) { \
- .name = #_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 %s()"
-
- /**
- * 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->name
-
- #endif /* _IPXE_PROCESS_H */
|