iPXE
process.h
Go to the documentation of this file.
1 #ifndef _IPXE_PROCESS_H
2 #define _IPXE_PROCESS_H
3 
4 /** @file
5  *
6  * Processes
7  *
8  */
9 
10 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11 FILE_SECBOOT ( PERMITTED );
12 
13 #include <ipxe/list.h>
14 #include <ipxe/refcnt.h>
15 #include <ipxe/tables.h>
16 
17 /** A process */
18 struct process {
19  /** List of processes */
20  struct list_head list;
21  /** Process descriptor */
23  /** Reference counter
24  *
25  * If this process is not part of a reference-counted object,
26  * this field may be NULL.
27  */
28  struct refcnt *refcnt;
29 };
30 
31 /** A process descriptor */
33  /** Process name */
34  const char *name;
35  /** Offset of process within containing object */
36  size_t offset;
37  /**
38  * Single-step the process
39  *
40  * This method should execute a single step of the process.
41  * Returning from this method is isomorphic to yielding the
42  * CPU to another process.
43  */
44  void ( * step ) ( void *object );
45  /** Automatically reschedule the process */
47 };
48 
49 /**
50  * Define a process step() method
51  *
52  * @v object_type Implementing method's expected object type
53  * @v step Implementing method
54  * @ret step Process step method
55  */
56 #define PROC_STEP( object_type, step ) \
57  ( ( ( ( typeof ( step ) * ) NULL ) == \
58  ( ( void ( * ) ( object_type *object ) ) NULL ) ) ? \
59  ( void ( * ) ( void *object ) ) step : \
60  ( void ( * ) ( void *object ) ) step )
61 
62 /**
63  * Calculate offset of process within containing object
64  *
65  * @v object_type Containing object data type
66  * @v name Process name (i.e. field within object data type)
67  * @ret offset Offset of process within containing object
68  */
69 #define process_offset( object_type, name ) \
70  ( ( ( ( typeof ( ( ( object_type * ) NULL )->name ) * ) NULL ) \
71  == ( ( struct process * ) NULL ) ) \
72  ? offsetof ( object_type, name ) \
73  : offsetof ( object_type, name ) )
74 
75 /**
76  * Define a process descriptor
77  *
78  * @v object_type Containing object data type
79  * @v process Process name (i.e. field within object data type)
80  * @v step Process' step() method
81  * @ret desc Object interface descriptor
82  */
83 #define PROC_DESC( object_type, process, _step ) { \
84  .name = #_step, \
85  .offset = process_offset ( object_type, process ), \
86  .step = PROC_STEP ( object_type, _step ), \
87  .reschedule = 1, \
88  }
89 
90 /**
91  * Define a process descriptor for a process that runs only once
92  *
93  * @v object_type Containing object data type
94  * @v process Process name (i.e. field within object data type)
95  * @v step Process' step() method
96  * @ret desc Object interface descriptor
97  */
98 #define PROC_DESC_ONCE( object_type, process, _step ) { \
99  .name = #_step, \
100  .offset = process_offset ( object_type, process ), \
101  .step = PROC_STEP ( object_type, _step ), \
102  .reschedule = 0, \
103  }
104 
105 /**
106  * Define a process descriptor for a pure process
107  *
108  * A pure process is a process that does not have a containing object.
109  *
110  * @v step Process' step() method
111  * @ret desc Object interface descriptor
112  */
113 #define PROC_DESC_PURE( _step ) { \
114  .name = #_step, \
115  .offset = 0, \
116  .step = PROC_STEP ( struct process, _step ), \
117  .reschedule = 1, \
118  }
119 
120 extern void * __attribute__ (( pure ))
121 process_object ( struct process *process );
122 extern void process_add ( struct process *process );
123 extern void process_del ( struct process *process );
124 extern void step ( void );
125 
126 /**
127  * Initialise a static process
128  *
129  * @v process Process
130  * @v desc Process descriptor
131  */
132 #define PROC_INIT( _process, _desc ) { \
133  .list = LIST_HEAD_INIT ( (_process).list ), \
134  .desc = (_desc), \
135  .refcnt = NULL, \
136  }
137 
138 /**
139  * Initialise process without adding to process list
140  *
141  * @v process Process
142  * @v desc Process descriptor
143  * @v refcnt Containing object reference count, or NULL
144  */
145 static inline __attribute__ (( always_inline )) void
147  struct process_descriptor *desc,
148  struct refcnt *refcnt ) {
150  process->desc = desc;
151  process->refcnt = refcnt;
152 }
153 
154 /**
155  * Initialise process and add to process list
156  *
157  * @v process Process
158  * @v desc Process descriptor
159  * @v refcnt Containing object reference count, or NULL
160  */
161 static inline __attribute__ (( always_inline )) void
163  struct process_descriptor *desc,
164  struct refcnt *refcnt ) {
166  process_add ( process );
167 }
168 
169 /**
170  * Check if process is running
171  *
172  * @v process Process
173  * @ret running Process is running
174  */
175 static inline __attribute__ (( always_inline )) int
177  return ( ! list_empty ( &process->list ) );
178 }
179 
180 /** Permanent process table */
181 #define PERMANENT_PROCESSES __table ( struct process, "processes" )
182 
183 /**
184  * Declare a permanent process
185  *
186  * Permanent processes will be automatically added to the process list
187  * at initialisation time.
188  */
189 #define __permanent_process __table_entry ( PERMANENT_PROCESSES, 01 )
190 
191 /** Define a permanent process
192  *
193  */
194 #define PERMANENT_PROCESS( name, step ) \
195 static struct process_descriptor name ## _desc = PROC_DESC_PURE ( step ); \
196 struct process name __permanent_process = PROC_INIT ( name, & name ## _desc );
197 
198 /**
199  * Find debugging colourisation for a process
200  *
201  * @v process Process
202  * @ret col Debugging colourisation
203  *
204  * Use as the first argument to DBGC() or equivalent macro.
205  */
206 #define PROC_COL( process ) process_object ( process )
207 
208 /** printf() format string for PROC_DBG() */
209 #define PROC_FMT "%p %s()"
210 
211 /**
212  * printf() arguments for representing a process
213  *
214  * @v process Process
215  * @ret args printf() argument list corresponding to PROC_FMT
216  */
217 #define PROC_DBG( process ) process_object ( process ), (process)->desc->name
218 
219 #endif /* _IPXE_PROCESS_H */
A process.
Definition: process.h:18
#define __attribute__(x)
Definition: compiler.h:10
size_t offset
Offset of process within containing object.
Definition: process.h:36
static void process_init(struct process *process, struct process_descriptor *desc, struct refcnt *refcnt)
Initialise process and add to process list.
Definition: process.h:162
const char * name
Process name.
Definition: process.h:34
A process descriptor.
Definition: process.h:32
struct list_head list
List of processes.
Definition: process.h:20
static void(*) struct refcnt refcnt)
Definition: pool.h:63
A doubly-linked list entry (or list head)
Definition: list.h:19
A reference counter.
Definition: refcnt.h:27
void process_del(struct process *process)
Remove process from process list.
Definition: process.c:80
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:137
void * process_object(struct process *process)
Get pointer to object containing process.
Definition: process.c:48
struct ena_llq_option desc
Descriptor counts.
Definition: ena.h:20
Linked lists.
void process_add(struct process *process)
Add process to process list.
Definition: process.c:60
static void process_init_stopped(struct process *process, struct process_descriptor *desc, struct refcnt *refcnt)
Initialise process without adding to process list.
Definition: process.h:146
static int process_running(struct process *process)
Check if process is running.
Definition: process.h:176
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:46
void step(void)
Single-step a single process.
Definition: process.c:99
FILE_SECBOOT(PERMITTED)
int reschedule
Automatically reschedule the process.
Definition: process.h:46
Reference counting.
Linker tables.
struct process_descriptor * desc
Process descriptor.
Definition: process.h:22
void(* step)(void *object)
Single-step the process.
Definition: process.h:44
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
struct refcnt * refcnt
Reference counter.
Definition: process.h:28