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 FILE_SECBOOT ( PERMITTED );
26 
27 #include <ipxe/list.h>
28 #include <ipxe/init.h>
29 #include <ipxe/process.h>
30 
31 /** @file
32  *
33  * Processes
34  *
35  * We implement a trivial form of cooperative multitasking, in which
36  * all processes share a single stack and address space.
37  */
38 
39 /** Process run queue */
40 static LIST_HEAD ( run_queue );
41 
42 /**
43  * Get pointer to object containing process
44  *
45  * @v process Process
46  * @ret object Containing object
47  */
48 void * process_object ( struct process *process ) {
49  return ( ( ( void * ) process ) - process->desc->offset );
50 }
51 
52 /**
53  * Add process to process list
54  *
55  * @v process Process
56  *
57  * It is safe to call process_add() multiple times; further calls will
58  * have no effect.
59  */
60 void process_add ( struct process *process ) {
61  if ( ! process_running ( process ) ) {
62  DBGC ( PROC_COL ( process ), "PROCESS " PROC_FMT
63  " starting\n", PROC_DBG ( process ) );
64  ref_get ( process->refcnt );
65  list_add_tail ( &process->list, &run_queue );
66  } else {
67  DBGC ( PROC_COL ( process ), "PROCESS " PROC_FMT
68  " already started\n", PROC_DBG ( process ) );
69  }
70 }
71 
72 /**
73  * Remove process from process list
74  *
75  * @v process Process
76  *
77  * It is safe to call process_del() multiple times; further calls will
78  * have no effect.
79  */
80 void process_del ( struct process *process ) {
81  if ( process_running ( process ) ) {
82  DBGC ( PROC_COL ( process ), "PROCESS " PROC_FMT
83  " stopping\n", PROC_DBG ( process ) );
84  list_del ( &process->list );
86  ref_put ( process->refcnt );
87  } else {
88  DBGC ( PROC_COL ( process ), "PROCESS " PROC_FMT
89  " already stopped\n", PROC_DBG ( process ) );
90  }
91 }
92 
93 /**
94  * Single-step a single process
95  *
96  * This executes a single step of the first process in the run queue,
97  * and moves the process to the end of the run queue.
98  */
99 void step ( void ) {
100  struct process *process;
101  struct process_descriptor *desc;
102  void *object;
103 
104  if ( ( process = list_first_entry ( &run_queue, struct process,
105  list ) ) ) {
106  ref_get ( process->refcnt ); /* Inhibit destruction mid-step */
107  desc = process->desc;
108  object = process_object ( process );
109  if ( desc->reschedule ) {
110  list_del ( &process->list );
111  list_add_tail ( &process->list, &run_queue );
112  } else {
113  process_del ( process );
114  }
115  DBGC2 ( PROC_COL ( process ), "PROCESS " PROC_FMT
116  " executing\n", PROC_DBG ( process ) );
117  desc->step ( object );
118  DBGC2 ( PROC_COL ( process ), "PROCESS " PROC_FMT
119  " finished executing\n", PROC_DBG ( process ) );
120  ref_put ( process->refcnt ); /* Allow destruction */
121  }
122 }
123 
124 /**
125  * Initialise processes
126  *
127  */
128 static void init_processes ( void ) {
129  struct process *process;
130 
132  process_add ( process );
133 }
134 
135 /** Process initialiser */
136 struct init_fn process_init_fn __init_fn ( INIT_NORMAL ) = {
137  .name = "process",
138  .initialise = init_processes,
139 };
A process.
Definition: process.h:18
size_t offset
Offset of process within containing object.
Definition: process.h:36
static void init_processes(void)
Initialise processes.
Definition: process.c:128
#define DBGC(...)
Definition: compiler.h:505
A process descriptor.
Definition: process.h:32
struct list_head list
List of processes.
Definition: process.h:20
#define PERMANENT_PROCESSES
Permanent process table.
Definition: process.h:181
void process_del(struct process *process)
Remove process from process list.
Definition: process.c:80
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition: list.h:334
#define list_del(list)
Delete an entry from a list.
Definition: list.h:120
struct ena_llq_option desc
Descriptor counts.
Definition: ena.h:20
#define INIT_NORMAL
Normal initialisation.
Definition: init.h:32
An initialisation function.
Definition: init.h:15
void * process_object(struct process *process)
Get pointer to object containing process.
Definition: process.c:48
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:94
const char * name
Definition: init.h:16
void process_add(struct process *process)
Add process to process list.
Definition: process.c:60
Linked lists.
FILE_SECBOOT(PERMITTED)
#define ref_get(refcnt)
Get additional reference to object.
Definition: refcnt.h:93
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:386
Processes.
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
#define PROC_DBG(process)
printf() arguments for representing a process
Definition: process.h:217
#define DBGC2(...)
Definition: compiler.h:522
void step(void)
Single-step a single process.
Definition: process.c:99
static LIST_HEAD(run_queue)
Process run queue.
struct process_descriptor * desc
Process descriptor.
Definition: process.h:22
#define PROC_COL(process)
Find debugging colourisation for a process.
Definition: process.h:206
#define PROC_FMT
printf() format string for PROC_DBG()
Definition: process.h:209
struct refcnt * refcnt
Reference counter.
Definition: process.h:28
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:107
struct init_fn process_init_fn __init_fn(INIT_NORMAL)
Process initialiser.
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)