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
10FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11FILE_SECBOOT ( PERMITTED );
12
13#include <ipxe/list.h>
14#include <ipxe/refcnt.h>
15#include <ipxe/tables.h>
16
17/** A process */
18struct process {
19 /** List of processes */
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
120extern void * __attribute__ (( pure ))
121process_object ( struct process *process );
122extern void process_add ( struct process *process );
123extern void process_del ( struct process *process );
124extern 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 */
145static inline __attribute__ (( always_inline )) void
147 struct process_descriptor *desc,
148 struct refcnt *refcnt ) {
150 process->desc = desc;
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 */
161static inline __attribute__ (( always_inline )) void
168
169/**
170 * Check if process is running
171 *
172 * @v process Process
173 * @ret running Process is running
174 */
175static 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 ) \
195static struct process_descriptor name ## _desc = PROC_DESC_PURE ( step ); \
196struct 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 */
struct ena_llq_option desc
Descriptor counts.
Definition ena.h:9
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
#define __attribute__(x)
Definition compiler.h:10
Linked lists.
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition list.h:46
#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
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
void process_del(struct process *process)
Remove process from process list.
Definition process.c:80
static int process_running(struct process *process)
Check if process is running.
Definition process.h:176
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
void step(void)
Single-step a single process.
Definition process.c:99
void process_add(struct process *process)
Add process to process list.
Definition process.c:60
Reference counting.
A doubly-linked list entry (or list head)
Definition list.h:19
A process descriptor.
Definition process.h:32
const char * name
Process name.
Definition process.h:34
int reschedule
Automatically reschedule the process.
Definition process.h:46
size_t offset
Offset of process within containing object.
Definition process.h:36
void(* step)(void *object)
Single-step the process.
Definition process.h:44
A process.
Definition process.h:18
struct list_head list
List of processes.
Definition process.h:20
struct refcnt * refcnt
Reference counter.
Definition process.h:28
struct process_descriptor * desc
Process descriptor.
Definition process.h:22
A reference counter.
Definition refcnt.h:27
Linker tables.