diff --git a/src/core/process.c b/src/core/process.c index c6660f22..4a705ef6 100644 --- a/src/core/process.c +++ b/src/core/process.c @@ -100,8 +100,12 @@ void step ( void ) { ref_get ( process->refcnt ); /* Inhibit destruction mid-step */ desc = process->desc; object = process_object ( process ); - list_del ( &process->list ); - list_add_tail ( &process->list, &run_queue ); + if ( desc->reschedule ) { + list_del ( &process->list ); + list_add_tail ( &process->list, &run_queue ); + } else { + process_del ( process ); + } DBGC2 ( PROC_COL ( process ), "PROCESS " PROC_FMT " executing\n", PROC_DBG ( process ) ); desc->step ( object ); diff --git a/src/include/ipxe/process.h b/src/include/ipxe/process.h index f8b10a8a..9b757981 100644 --- a/src/include/ipxe/process.h +++ b/src/include/ipxe/process.h @@ -39,6 +39,8 @@ struct process_descriptor { * CPU to another process. */ void ( * step ) ( void *object ); + /** Automatically reschedule the process */ + int reschedule; }; /** @@ -78,6 +80,21 @@ struct process_descriptor { #define PROC_DESC( object_type, process, _step ) { \ .offset = process_offset ( object_type, process ), \ .step = PROC_STEP ( object_type, _step ), \ + .reschedule = 1, \ + } + +/** + * Define a process descriptor for a process that runs only once + * + * @v object_type Containing object data type + * @v process Process name (i.e. field within object data type) + * @v step Process' step() method + * @ret desc Object interface descriptor + */ +#define PROC_DESC_ONCE( object_type, process, _step ) { \ + .offset = process_offset ( object_type, process ), \ + .step = PROC_STEP ( object_type, _step ), \ + .reschedule = 0, \ } /** @@ -91,6 +108,7 @@ struct process_descriptor { #define PROC_DESC_PURE( _step ) { \ .offset = 0, \ .step = PROC_STEP ( struct process, _step ), \ + .reschedule = 1, \ } extern void * __attribute__ (( pure ))