[process] Make it safe to call process_add() multiple times
[people/peper/gpxe.git] / src / include / gpxe / process.h
1 #ifndef _GPXE_PROCESS_H
2 #define _GPXE_PROCESS_H
3
4 /** @file
5  *
6  * Processes
7  *
8  */
9
10 FILE_LICENCE ( GPL2_OR_LATER );
11
12 #include <gpxe/list.h>
13 #include <gpxe/refcnt.h>
14 #include <gpxe/tables.h>
15
16 /** A process */
17 struct process {
18         /** List of processes */
19         struct list_head list;
20         /**
21          * Single-step the process
22          *
23          * This method should execute a single step of the process.
24          * Returning from this method is isomorphic to yielding the
25          * CPU to another process.
26          */
27         void ( * step ) ( struct process *process );
28         /** Reference counter
29          *
30          * If this interface is not part of a reference-counted
31          * object, this field may be NULL.
32          */
33         struct refcnt *refcnt;
34 };
35
36 extern void process_add ( struct process *process );
37 extern void process_del ( struct process *process );
38 extern void step ( void );
39
40 /**
41  * Initialise process without adding to process list
42  *
43  * @v process           Process
44  * @v step              Process' step() method
45  */
46 static inline __attribute__ (( always_inline )) void
47 process_init_stopped ( struct process *process,
48                        void ( * step ) ( struct process *process ),
49                        struct refcnt *refcnt ) {
50         INIT_LIST_HEAD ( &process->list );
51         process->step = step;
52         process->refcnt = refcnt;
53 }
54
55 /**
56  * Initialise process and add to process list
57  *
58  * @v process           Process
59  * @v step              Process' step() method
60  */
61 static inline __attribute__ (( always_inline )) void
62 process_init ( struct process *process,
63                void ( * step ) ( struct process *process ),
64                struct refcnt *refcnt ) {
65         process_init_stopped ( process, step, refcnt );
66         process_add ( process );
67 }
68
69 /** Permanent process table */
70 #define PERMANENT_PROCESSES __table ( struct process, "processes" )
71
72 /**
73  * Declare a permanent process
74  *
75  * Permanent processes will be automatically added to the process list
76  * at initialisation time.
77  */
78 #define __permanent_process __table_entry ( PERMANENT_PROCESSES, 01 )
79
80 #endif /* _GPXE_PROCESS_H */