Преглед на файлове

Modify process semantics; rescheduling is now automatic.

Add reference-counting to processes.

Add timer_running() test.
tags/v0.9.3
Michael Brown преди 17 години
родител
ревизия
3601103381
променени са 5 файла, в които са добавени 76 реда и са изтрити 19 реда
  1. 22
    4
      src/core/process.c
  2. 37
    4
      src/include/gpxe/process.h
  3. 11
    0
      src/include/gpxe/retry.h
  4. 2
    5
      src/net/netdevice.c
  5. 4
    6
      src/net/retry.c

+ 22
- 4
src/core/process.c Целия файл

@@ -31,25 +31,43 @@
31 31
 static LIST_HEAD ( run_queue );
32 32
 
33 33
 /**
34
- * Add process to run queue
34
+ * Add process to process list
35 35
  *
36 36
  * @v process		Process
37 37
  */
38
-void schedule ( struct process *process ) {
38
+void process_add ( struct process *process ) {
39
+	ref_get ( process->refcnt );
39 40
 	list_add_tail ( &process->list, &run_queue );
40 41
 }
41 42
 
43
+/**
44
+ * Remove process from process list
45
+ *
46
+ * @v process		Process
47
+ *
48
+ * It is safe to call process_del() multiple times; further calls will
49
+ * have no effect.
50
+ */
51
+void process_del ( struct process *process ) {
52
+	if ( ! list_empty ( &process->list ) ) {
53
+		list_del ( &process->list );
54
+		INIT_LIST_HEAD ( &process->list );
55
+		ref_put ( process->refcnt );
56
+	}
57
+}
58
+
42 59
 /**
43 60
  * Single-step a single process
44 61
  *
45
- * This removes the first process from the run queue and executes a
46
- * single step of that process.
62
+ * This executes a single step of the first process in the run queue,
63
+ * and moves the process to the end of the run queue.
47 64
  */
48 65
 void step ( void ) {
49 66
 	struct process *process;
50 67
 
51 68
 	list_for_each_entry ( process, &run_queue, list ) {
52 69
 		list_del ( &process->list );
70
+		list_add_tail ( &process->list, &run_queue );
53 71
 		process->step ( process );
54 72
 		break;
55 73
 	}

+ 37
- 4
src/include/gpxe/process.h Целия файл

@@ -8,6 +8,7 @@
8 8
  */
9 9
 
10 10
 #include <gpxe/list.h>
11
+#include <gpxe/refcnt.h>
11 12
 
12 13
 /** A process */
13 14
 struct process {
@@ -19,14 +20,46 @@ struct process {
19 20
 	 * This method should execute a single step of the process.
20 21
 	 * Returning from this method is isomorphic to yielding the
21 22
 	 * CPU to another process.
22
-	 *
23
-	 * If the process wishes to be executed again, it must re-add
24
-	 * itself to the run queue using schedule().
25 23
 	 */
26 24
 	void ( * step ) ( struct process *process );
25
+	/** Reference counter
26
+	 *
27
+	 * If this interface is not part of a reference-counted
28
+	 * object, this field may be NULL.
29
+	 */
30
+	struct refcnt *refcnt;
27 31
 };
28 32
 
29
-extern void schedule ( struct process *process );
33
+extern void process_add ( struct process *process );
34
+extern void process_del ( struct process *process );
30 35
 extern void step ( void );
31 36
 
37
+/**
38
+ * Initialise process without adding to process list
39
+ *
40
+ * @v process		Process
41
+ * @v step		Process' step() method
42
+ */
43
+static inline __attribute__ (( always_inline )) void
44
+process_init_stopped ( struct process *process,
45
+		       void ( * step ) ( struct process *process ),
46
+		       struct refcnt *refcnt ) {
47
+	process->step = step;
48
+	process->refcnt = refcnt;
49
+}
50
+
51
+/**
52
+ * Initialise process and add to process list
53
+ *
54
+ * @v process		Process
55
+ * @v step		Process' step() method
56
+ */
57
+static inline __attribute__ (( always_inline )) void
58
+process_init ( struct process *process,
59
+	       void ( * step ) ( struct process *process ),
60
+	       struct refcnt *refcnt ) {
61
+	process_init_stopped ( process, step, refcnt );
62
+	process_add ( process );
63
+}
64
+
32 65
 #endif /* _GPXE_PROCESS_H */

+ 11
- 0
src/include/gpxe/retry.h Целия файл

@@ -37,4 +37,15 @@ struct retry_timer {
37 37
 extern void start_timer ( struct retry_timer *timer );
38 38
 extern void stop_timer ( struct retry_timer *timer );
39 39
 
40
+/**
41
+ * Test to see if timer is currently running
42
+ *
43
+ * @v timer		Retry timer
44
+ * @ret running		Non-zero if timer is running
45
+ */
46
+static inline __attribute__ (( always_inline )) unsigned long
47
+timer_running ( struct retry_timer *timer ) {
48
+	return ( timer->start );
49
+}
50
+
40 51
 #endif /* _GPXE_RETRY_H */

+ 2
- 5
src/net/netdevice.c Целия файл

@@ -388,7 +388,7 @@ int net_rx ( struct io_buffer *iobuf, struct net_device *netdev,
388 388
  * This polls all interfaces for received packets, and processes
389 389
  * packets from the RX queue.
390 390
  */
391
-static void net_step ( struct process *process ) {
391
+static void net_step ( struct process *process __unused ) {
392 392
 	struct net_device *netdev;
393 393
 	struct io_buffer *iobuf;
394 394
 
@@ -410,9 +410,6 @@ static void net_step ( struct process *process ) {
410 410
 			netdev->ll_protocol->rx ( iobuf, netdev );
411 411
 		}
412 412
 	}
413
-
414
-	/* Re-schedule ourself */
415
-	schedule ( process );
416 413
 }
417 414
 
418 415
 /** Networking stack process */
@@ -422,7 +419,7 @@ static struct process net_process = {
422 419
 
423 420
 /** Initialise the networking stack process */
424 421
 static void init_net ( void ) {
425
-	schedule ( &net_process );
422
+	process_add ( &net_process );
426 423
 }
427 424
 
428 425
 INIT_FN ( INIT_PROCESS, init_net, NULL, NULL );

+ 4
- 6
src/net/retry.c Целия файл

@@ -64,7 +64,7 @@ static LIST_HEAD ( timers );
64 64
  * be stopped and the timer's callback function will be called.
65 65
  */
66 66
 void start_timer ( struct retry_timer *timer ) {
67
-	if ( ! timer->start )
67
+	if ( ! timer_running ( timer ) )
68 68
 		list_add ( &timer->list, &timers );
69 69
 	timer->start = currticks();
70 70
 	if ( timer->timeout < MIN_TIMEOUT )
@@ -86,7 +86,7 @@ void stop_timer ( struct retry_timer *timer ) {
86 86
 	unsigned long runtime;
87 87
 
88 88
 	/* If timer was already stopped, do nothing */
89
-	if ( ! timer->start )
89
+	if ( ! timer_running ( timer ) )
90 90
 		return;
91 91
 
92 92
 	list_del ( &timer->list );
@@ -153,7 +153,7 @@ static void timer_expired ( struct retry_timer *timer ) {
153 153
  *
154 154
  * @v process		Retry timer process
155 155
  */
156
-static void retry_step ( struct process *process ) {
156
+static void retry_step ( struct process *process __unused ) {
157 157
 	struct retry_timer *timer;
158 158
 	struct retry_timer *tmp;
159 159
 	unsigned long now = currticks();
@@ -164,8 +164,6 @@ static void retry_step ( struct process *process ) {
164 164
 		if ( used >= timer->timeout )
165 165
 			timer_expired ( timer );
166 166
 	}
167
-
168
-	schedule ( process );
169 167
 }
170 168
 
171 169
 /** Retry timer process */
@@ -175,7 +173,7 @@ static struct process retry_process = {
175 173
 
176 174
 /** Initialise the retry timer module */
177 175
 static void init_retry ( void ) {
178
-	schedule ( &retry_process );
176
+	process_add ( &retry_process );
179 177
 }
180 178
 
181 179
 INIT_FN ( INIT_PROCESS, init_retry, NULL, NULL );

Loading…
Отказ
Запис