iPXE
process.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 #include <ipxe/list.h>
27 #include <ipxe/init.h>
28 #include <ipxe/process.h>
29 
30 /** @file
31  *
32  * Processes
33  *
34  * We implement a trivial form of cooperative multitasking, in which
35  * all processes share a single stack and address space.
36  */
37 
38 /** Process run queue */
39 static LIST_HEAD ( run_queue );
40 
41 /**
42  * Get pointer to object containing process
43  *
44  * @v process Process
45  * @ret object Containing object
46  */
47 void * process_object ( struct process *process ) {
48  return ( ( ( void * ) process ) - process->desc->offset );
49 }
50 
51 /**
52  * Add process to process list
53  *
54  * @v process Process
55  *
56  * It is safe to call process_add() multiple times; further calls will
57  * have no effect.
58  */
59 void process_add ( struct process *process ) {
60  if ( ! process_running ( process ) ) {
61  DBGC ( PROC_COL ( process ), "PROCESS " PROC_FMT
62  " starting\n", PROC_DBG ( process ) );
63  ref_get ( process->refcnt );
64  list_add_tail ( &process->list, &run_queue );
65  } else {
66  DBGC ( PROC_COL ( process ), "PROCESS " PROC_FMT
67  " already started\n", PROC_DBG ( process ) );
68  }
69 }
70 
71 /**
72  * Remove process from process list
73  *
74  * @v process Process
75  *
76  * It is safe to call process_del() multiple times; further calls will
77  * have no effect.
78  */
79 void process_del ( struct process *process ) {
80  if ( process_running ( process ) ) {
81  DBGC ( PROC_COL ( process ), "PROCESS " PROC_FMT
82  " stopping\n", PROC_DBG ( process ) );
83  list_del ( &process->list );
85  ref_put ( process->refcnt );
86  } else {
87  DBGC ( PROC_COL ( process ), "PROCESS " PROC_FMT
88  " already stopped\n", PROC_DBG ( process ) );
89  }
90 }
91 
92 /**
93  * Single-step a single process
94  *
95  * This executes a single step of the first process in the run queue,
96  * and moves the process to the end of the run queue.
97  */
98 void step ( void ) {
99  struct process *process;
100  struct process_descriptor *desc;
101  void *object;
102 
103  if ( ( process = list_first_entry ( &run_queue, struct process,
104  list ) ) ) {
105  ref_get ( process->refcnt ); /* Inhibit destruction mid-step */
106  desc = process->desc;
107  object = process_object ( process );
108  if ( desc->reschedule ) {
109  list_del ( &process->list );
110  list_add_tail ( &process->list, &run_queue );
111  } else {
112  process_del ( process );
113  }
114  DBGC2 ( PROC_COL ( process ), "PROCESS " PROC_FMT
115  " executing\n", PROC_DBG ( process ) );
116  desc->step ( object );
117  DBGC2 ( PROC_COL ( process ), "PROCESS " PROC_FMT
118  " finished executing\n", PROC_DBG ( process ) );
119  ref_put ( process->refcnt ); /* Allow destruction */
120  }
121 }
122 
123 /**
124  * Initialise processes
125  *
126  */
127 static void init_processes ( void ) {
128  struct process *process;
129 
131  process_add ( process );
132 }
133 
134 /** Process initialiser */
135 struct init_fn process_init_fn __init_fn ( INIT_NORMAL ) = {
137 };
A process.
Definition: process.h:17
void(* initialise)(void)
Definition: init.h:15
size_t offset
Offset of process within containing object.
Definition: process.h:35
static void init_processes(void)
Initialise processes.
Definition: process.c:127
#define DBGC(...)
Definition: compiler.h:505
A process descriptor.
Definition: process.h:31
struct list_head list
List of processes.
Definition: process.h:19
#define PERMANENT_PROCESSES
Permanent process table.
Definition: process.h:180
void process_del(struct process *process)
Remove process from process list.
Definition: process.c:79
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition: list.h:333
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
#define INIT_NORMAL
Normal initialisation.
Definition: init.h:30
An initialisation function.
Definition: init.h:14
void * process_object(struct process *process)
Get pointer to object containing process.
Definition: process.c:47
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
void process_add(struct process *process)
Add process to process list.
Definition: process.c:59
Linked lists.
#define ref_get(refcnt)
Get additional reference to object.
Definition: refcnt.h:92
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:358
Processes.
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
#define PROC_DBG(process)
printf() arguments for representing a process
Definition: process.h:216
#define DBGC2(...)
Definition: compiler.h:522
int reschedule
Automatically reschedule the process.
Definition: process.h:45
void step(void)
Single-step a single process.
Definition: process.c:98
static LIST_HEAD(run_queue)
Process run queue.
struct process_descriptor * desc
Process descriptor.
Definition: process.h:21
#define PROC_COL(process)
Find debugging colourisation for a process.
Definition: process.h:205
#define PROC_FMT
printf() format string for PROC_DBG()
Definition: process.h:208
void(* step)(void *object)
Single-step the process.
Definition: process.h:43
struct refcnt * refcnt
Reference counter.
Definition: process.h:27
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106
struct init_fn process_init_fn __init_fn(INIT_NORMAL)
Process initialiser.
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)