aboutsummaryrefslogtreecommitdiffstats
path: root/src/include/ipxe/process.h
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2011-06-24 14:14:41 +0100
committerMichael Brown <mcb30@ipxe.org>2011-06-28 14:45:08 +0100
commite01ec74601b58f54a5e2ae7b9fd1196972034114 (patch)
tree54f2d2202274523e2365584502dee7db8deca43b /src/include/ipxe/process.h
parentba3633782bd36831ca5471d792e626b7e8344e0c (diff)
downloadipxe-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.h122
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 */