mirror of
https://github.com/ipxe/ipxe
synced 2025-12-24 15:23:42 +03:00
[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>
This commit is contained in:
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user