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