process.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License as
00006  * published by the Free Software Foundation; either version 2 of the
00007  * License, or any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00017  */
00018 
00019 FILE_LICENCE ( GPL2_OR_LATER );
00020 
00021 #include <gpxe/list.h>
00022 #include <gpxe/init.h>
00023 #include <gpxe/process.h>
00024 
00025 /** @file
00026  *
00027  * Processes
00028  *
00029  * We implement a trivial form of cooperative multitasking, in which
00030  * all processes share a single stack and address space.
00031  */
00032 
00033 /** Process run queue */
00034 static LIST_HEAD ( run_queue );
00035 
00036 /**
00037  * Add process to process list
00038  *
00039  * @v process           Process
00040  *
00041  * It is safe to call process_add() multiple times; further calls will
00042  * have no effect.
00043  */
00044 void process_add ( struct process *process ) {
00045         if ( list_empty ( &process->list ) ) {
00046                 DBGC ( process, "PROCESS %p starting\n", process );
00047                 ref_get ( process->refcnt );
00048                 list_add_tail ( &process->list, &run_queue );
00049         } else {
00050                 DBGC ( process, "PROCESS %p already started\n", process );
00051         }
00052 }
00053 
00054 /**
00055  * Remove process from process list
00056  *
00057  * @v process           Process
00058  *
00059  * It is safe to call process_del() multiple times; further calls will
00060  * have no effect.
00061  */
00062 void process_del ( struct process *process ) {
00063         if ( ! list_empty ( &process->list ) ) {
00064                 DBGC ( process, "PROCESS %p stopping\n", process );
00065                 list_del ( &process->list );
00066                 INIT_LIST_HEAD ( &process->list );
00067                 ref_put ( process->refcnt );
00068         } else {
00069                 DBGC ( process, "PROCESS %p already stopped\n", process );
00070         }
00071 }
00072 
00073 /**
00074  * Single-step a single process
00075  *
00076  * This executes a single step of the first process in the run queue,
00077  * and moves the process to the end of the run queue.
00078  */
00079 void step ( void ) {
00080         struct process *process;
00081 
00082         list_for_each_entry ( process, &run_queue, list ) {
00083                 list_del ( &process->list );
00084                 list_add_tail ( &process->list, &run_queue );
00085                 DBGC2 ( process, "PROCESS %p executing\n", process );
00086                 process->step ( process );
00087                 DBGC2 ( process, "PROCESS %p finished executing\n", process );
00088                 break;
00089         }
00090 }
00091 
00092 /**
00093  * Initialise processes
00094  *
00095  */
00096 static void init_processes ( void ) {
00097         struct process *process;
00098 
00099         for_each_table_entry ( process, PERMANENT_PROCESSES )
00100                 process_add ( process );
00101 }
00102 
00103 /** Process initialiser */
00104 struct init_fn process_init_fn __init_fn ( INIT_NORMAL ) = {
00105         .initialise = init_processes,
00106 };

Generated on Tue Apr 6 20:00:51 2010 for gPXE by  doxygen 1.5.7.1