[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:
Michael Brown
2011-06-24 14:14:41 +01:00
parent ba3633782b
commit e01ec74601
16 changed files with 229 additions and 101 deletions

View File

@@ -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 */