diff options
author | Michael Brown <mcb30@ipxe.org> | 2011-06-24 14:14:41 +0100 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2011-06-28 14:45:08 +0100 |
commit | e01ec74601b58f54a5e2ae7b9fd1196972034114 (patch) | |
tree | 54f2d2202274523e2365584502dee7db8deca43b /src/include/ipxe/process.h | |
parent | ba3633782bd36831ca5471d792e626b7e8344e0c (diff) | |
download | ipxe-e01ec74601b58f54a5e2ae7b9fd1196972034114.tar.gz |
[process] Pass containing object pointer to process step() methods
Give the step() method a pointer to the containing object, rather than
a pointer to the process. This is consistent with the operation of
interface methods, and allows a single function to serve as both an
interface method and a process step() method.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/include/ipxe/process.h')
-rw-r--r-- | src/include/ipxe/process.h | 122 |
1 files changed, 109 insertions, 13 deletions
diff --git a/src/include/ipxe/process.h b/src/include/ipxe/process.h index 45c2af639..f8b10a8ae 100644 --- a/src/include/ipxe/process.h +++ b/src/include/ipxe/process.h @@ -17,6 +17,20 @@ FILE_LICENCE ( GPL2_OR_LATER ); 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 * @@ -24,15 +38,63 @@ struct process { * Returning from this method is isomorphic to yielding the * CPU to another process. */ - void ( * step ) ( struct process *process ); - /** Reference counter - * - * If this interface is not part of a reference-counted - * object, this field may be NULL. - */ - struct refcnt *refcnt; + void ( * step ) ( void *object ); }; +/** + * 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 ), \ + } + +/** + * 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 ), \ + } + +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 ); @@ -41,14 +103,15 @@ extern void step ( void ); * Initialise process without adding to process list * * @v process Process - * @v step Process' step() method + * @v desc Process descriptor + * @v refcnt Containing object reference count, or NULL */ static inline __attribute__ (( always_inline )) void process_init_stopped ( struct process *process, - void ( * step ) ( struct process *process ), + struct process_descriptor *desc, struct refcnt *refcnt ) { INIT_LIST_HEAD ( &process->list ); - process->step = step; + process->desc = desc; process->refcnt = refcnt; } @@ -56,13 +119,14 @@ process_init_stopped ( struct process *process, * Initialise process and add to process list * * @v process Process - * @v step Process' step() method + * @v desc Process descriptor + * @v refcnt Containing object reference count, or NULL */ static inline __attribute__ (( always_inline )) void process_init ( struct process *process, - void ( * step ) ( struct process *process ), + struct process_descriptor *desc, struct refcnt *refcnt ) { - process_init_stopped ( process, step, refcnt ); + process_init_stopped ( process, desc, refcnt ); process_add ( process ); } @@ -88,4 +152,36 @@ process_running ( struct process *process ) { */ #define __permanent_process __table_entry ( PERMANENT_PROCESSES, 01 ) +/** Define a permanent process + * + */ +#define PERMANENT_PROCESS( name, step ) \ +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 */ |