1 #ifndef _IPXE_PROCESS_H
2 #define _IPXE_PROCESS_H
10 FILE_LICENCE ( GPL2_OR_LATER );
12 #include <ipxe/list.h>
13 #include <ipxe/refcnt.h>
14 #include <ipxe/tables.h>
18 /** List of processes */
19 struct list_head list;
20 /** Process descriptor */
21 struct process_descriptor *desc;
24 * If this process is not part of a reference-counted object,
25 * this field may be NULL.
27 struct refcnt *refcnt;
30 /** A process descriptor */
31 struct process_descriptor {
32 /** Offset of process within containing object */
35 * Single-step the process
37 * This method should execute a single step of the process.
38 * Returning from this method is isomorphic to yielding the
39 * CPU to another process.
41 void ( * step ) ( void *object );
42 /** Automatically reschedule the process */
47 * Define a process step() method
49 * @v object_type Implementing method's expected object type
50 * @v step Implementing method
51 * @ret step Process step method
53 #define PROC_STEP( object_type, step ) \
54 ( ( ( ( typeof ( step ) * ) NULL ) == \
55 ( ( void ( * ) ( object_type *object ) ) NULL ) ) ? \
56 ( void ( * ) ( void *object ) ) step : \
57 ( void ( * ) ( void *object ) ) step )
60 * Calculate offset of process within containing object
62 * @v object_type Containing object data type
63 * @v name Process name (i.e. field within object data type)
64 * @ret offset Offset of process within containing object
66 #define process_offset( object_type, name ) \
67 ( ( ( ( typeof ( ( ( object_type * ) NULL )->name ) * ) NULL ) \
68 == ( ( struct process * ) NULL ) ) \
69 ? offsetof ( object_type, name ) \
70 : offsetof ( object_type, name ) )
73 * Define a process descriptor
75 * @v object_type Containing object data type
76 * @v process Process name (i.e. field within object data type)
77 * @v step Process' step() method
78 * @ret desc Object interface descriptor
80 #define PROC_DESC( object_type, process, _step ) { \
81 .offset = process_offset ( object_type, process ), \
82 .step = PROC_STEP ( object_type, _step ), \
87 * Define a process descriptor for a process that runs only once
89 * @v object_type Containing object data type
90 * @v process Process name (i.e. field within object data type)
91 * @v step Process' step() method
92 * @ret desc Object interface descriptor
94 #define PROC_DESC_ONCE( object_type, process, _step ) { \
95 .offset = process_offset ( object_type, process ), \
96 .step = PROC_STEP ( object_type, _step ), \
101 * Define a process descriptor for a pure process
103 * A pure process is a process that does not have a containing object.
105 * @v step Process' step() method
106 * @ret desc Object interface descriptor
108 #define PROC_DESC_PURE( _step ) { \
110 .step = PROC_STEP ( struct process, _step ), \
114 extern void * __attribute__ (( pure ))
115 process_object ( struct process *process );
116 extern void process_add ( struct process *process );
117 extern void process_del ( struct process *process );
118 extern void step ( void );
121 * Initialise process without adding to process list
124 * @v desc Process descriptor
125 * @v refcnt Containing object reference count, or NULL
127 static inline __attribute__ (( always_inline )) void
128 process_init_stopped ( struct process *process,
129 struct process_descriptor *desc,
130 struct refcnt *refcnt ) {
131 INIT_LIST_HEAD ( &process->list );
132 process->desc = desc;
133 process->refcnt = refcnt;
137 * Initialise process and add to process list
140 * @v desc Process descriptor
141 * @v refcnt Containing object reference count, or NULL
143 static inline __attribute__ (( always_inline )) void
144 process_init ( struct process *process,
145 struct process_descriptor *desc,
146 struct refcnt *refcnt ) {
147 process_init_stopped ( process, desc, refcnt );
148 process_add ( process );
152 * Check if process is running
155 * @ret running Process is running
157 static inline __attribute__ (( always_inline )) int
158 process_running ( struct process *process ) {
159 return ( ! list_empty ( &process->list ) );
162 /** Permanent process table */
163 #define PERMANENT_PROCESSES __table ( struct process, "processes" )
166 * Declare a permanent process
168 * Permanent processes will be automatically added to the process list
169 * at initialisation time.
171 #define __permanent_process __table_entry ( PERMANENT_PROCESSES, 01 )
173 /** Define a permanent process
176 #define PERMANENT_PROCESS( name, step ) \
177 static struct process_descriptor name ## _desc = PROC_DESC_PURE ( step ); \
178 struct process name __permanent_process = { \
179 .list = LIST_HEAD_INIT ( name.list ), \
180 .desc = & name ## _desc, \
185 * Find debugging colourisation for a process
188 * @ret col Debugging colourisation
190 * Use as the first argument to DBGC() or equivalent macro.
192 #define PROC_COL( process ) process_object ( process )
194 /** printf() format string for PROC_DBG() */
195 #define PROC_FMT "%p+%zx"
198 * printf() arguments for representing a process
201 * @ret args printf() argument list corresponding to PROC_FMT
203 #define PROC_DBG( process ) process_object ( process ), (process)->desc->offset
205 #endif /* _IPXE_PROCESS_H */