Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / include / ipxe / process.h
diff --git a/qemu/roms/ipxe/src/include/ipxe/process.h b/qemu/roms/ipxe/src/include/ipxe/process.h
new file mode 100644 (file)
index 0000000..2c76ff2
--- /dev/null
@@ -0,0 +1,205 @@
+#ifndef _IPXE_PROCESS_H
+#define _IPXE_PROCESS_H
+
+/** @file
+ *
+ * Processes
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <ipxe/list.h>
+#include <ipxe/refcnt.h>
+#include <ipxe/tables.h>
+
+/** A process */
+struct process {
+       /** List of processes */
+       struct list_head list;
+       /** Process descriptor */
+       struct process_descriptor *desc;
+       /** Reference counter
+        *
+        * If this process is not part of a reference-counted object,
+        * this field may be NULL.
+        */
+       struct refcnt *refcnt;
+};
+
+/** A process descriptor */
+struct process_descriptor {
+       /** Offset of process within containing object */
+       size_t offset;
+       /**
+        * Single-step the process
+        *
+        * This method should execute a single step of the process.
+        * Returning from this method is isomorphic to yielding the
+        * CPU to another process.
+        */
+       void ( * step ) ( void *object );
+       /** Automatically reschedule the process */
+       int reschedule;
+};
+
+/**
+ * Define a process step() method
+ *
+ * @v object_type      Implementing method's expected object type
+ * @v step             Implementing method
+ * @ret step           Process step method
+ */
+#define PROC_STEP( object_type, step )                                       \
+       ( ( ( ( typeof ( step ) * ) NULL ) ==                                 \
+           ( ( void ( * ) ( object_type *object ) ) NULL ) ) ?               \
+         ( void ( * ) ( void *object ) ) step :                              \
+         ( void ( * ) ( void *object ) ) step )
+
+/**
+ * Calculate offset of process within containing object
+ *
+ * @v object_type      Containing object data type
+ * @v name             Process name (i.e. field within object data type)
+ * @ret offset         Offset of process within containing object
+ */
+#define process_offset( object_type, name )                                  \
+       ( ( ( ( typeof ( ( ( object_type * ) NULL )->name ) * ) NULL )        \
+           == ( ( struct process * ) NULL ) )                                \
+         ? offsetof ( object_type, name )                                    \
+         : offsetof ( object_type, name ) )
+
+/**
+ * Define a process descriptor
+ *
+ * @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( 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,                                              \
+       }
+
+/**
+ * Define a process descriptor for a pure process
+ *
+ * A pure process is a process that does not have a containing object.
+ *
+ * @v step             Process' step() method
+ * @ret desc           Object interface descriptor
+ */
+#define PROC_DESC_PURE( _step ) {                                            \
+               .offset = 0,                                                  \
+               .step = PROC_STEP ( struct process, _step ),                  \
+               .reschedule = 1,                                              \
+       }
+
+extern void * __attribute__ (( pure ))
+process_object ( struct process *process );
+extern void process_add ( struct process *process );
+extern void process_del ( struct process *process );
+extern void step ( void );
+
+/**
+ * Initialise process without adding to process list
+ *
+ * @v process          Process
+ * @v desc             Process descriptor
+ * @v refcnt           Containing object reference count, or NULL
+ */
+static inline __attribute__ (( always_inline )) void
+process_init_stopped ( struct process *process,
+                      struct process_descriptor *desc,
+                      struct refcnt *refcnt ) {
+       INIT_LIST_HEAD ( &process->list );
+       process->desc = desc;
+       process->refcnt = refcnt;
+}
+
+/**
+ * Initialise process and add to process list
+ *
+ * @v process          Process
+ * @v desc             Process descriptor
+ * @v refcnt           Containing object reference count, or NULL
+ */
+static inline __attribute__ (( always_inline )) void
+process_init ( struct process *process,
+              struct process_descriptor *desc,
+              struct refcnt *refcnt ) {
+       process_init_stopped ( process, desc, refcnt );
+       process_add ( process );
+}
+
+/**
+ * Check if process is running
+ *
+ * @v process          Process
+ * @ret running                Process is running
+ */
+static inline __attribute__ (( always_inline )) int
+process_running ( struct process *process ) {
+       return ( ! list_empty ( &process->list ) );
+}
+
+/** Permanent process table */
+#define PERMANENT_PROCESSES __table ( struct process, "processes" )
+
+/**
+ * Declare a permanent process
+ *
+ * Permanent processes will be automatically added to the process list
+ * at initialisation time.
+ */
+#define __permanent_process __table_entry ( PERMANENT_PROCESSES, 01 )
+
+/** Define a permanent process
+ *
+ */
+#define PERMANENT_PROCESS( name, step )                                              \
+static struct process_descriptor name ## _desc = PROC_DESC_PURE ( step );     \
+struct process name __permanent_process = {                                  \
+       .list = LIST_HEAD_INIT ( name.list ),                                 \
+       .desc = & name ## _desc,                                              \
+       .refcnt = NULL,                                                       \
+};
+
+/**
+ * Find debugging colourisation for a process
+ *
+ * @v process          Process
+ * @ret col            Debugging colourisation
+ *
+ * Use as the first argument to DBGC() or equivalent macro.
+ */
+#define PROC_COL( process ) process_object ( process )
+
+/** printf() format string for PROC_DBG() */
+#define PROC_FMT "%p+%zx"
+
+/**
+ * printf() arguments for representing a process
+ *
+ * @v process          Process
+ * @ret args           printf() argument list corresponding to PROC_FMT
+ */
+#define PROC_DBG( process ) process_object ( process ), (process)->desc->offset
+
+#endif /* _IPXE_PROCESS_H */