Browse Source

Modify process semantics; rescheduling is now automatic.

Add reference-counting to processes.

Add timer_running() test.
tags/v0.9.3
Michael Brown 17 years ago
parent
commit
3601103381
5 changed files with 76 additions and 19 deletions
  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 View File

31
 static LIST_HEAD ( run_queue );
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
  * @v process		Process
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
 	list_add_tail ( &process->list, &run_queue );
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
  * Single-step a single process
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
 void step ( void ) {
65
 void step ( void ) {
49
 	struct process *process;
66
 	struct process *process;
50
 
67
 
51
 	list_for_each_entry ( process, &run_queue, list ) {
68
 	list_for_each_entry ( process, &run_queue, list ) {
52
 		list_del ( &process->list );
69
 		list_del ( &process->list );
70
+		list_add_tail ( &process->list, &run_queue );
53
 		process->step ( process );
71
 		process->step ( process );
54
 		break;
72
 		break;
55
 	}
73
 	}

+ 37
- 4
src/include/gpxe/process.h View File

8
  */
8
  */
9
 
9
 
10
 #include <gpxe/list.h>
10
 #include <gpxe/list.h>
11
+#include <gpxe/refcnt.h>
11
 
12
 
12
 /** A process */
13
 /** A process */
13
 struct process {
14
 struct process {
19
 	 * This method should execute a single step of the process.
20
 	 * This method should execute a single step of the process.
20
 	 * Returning from this method is isomorphic to yielding the
21
 	 * Returning from this method is isomorphic to yielding the
21
 	 * CPU to another process.
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
 	void ( * step ) ( struct process *process );
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
 extern void step ( void );
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
 #endif /* _GPXE_PROCESS_H */
65
 #endif /* _GPXE_PROCESS_H */

+ 11
- 0
src/include/gpxe/retry.h View File

37
 extern void start_timer ( struct retry_timer *timer );
37
 extern void start_timer ( struct retry_timer *timer );
38
 extern void stop_timer ( struct retry_timer *timer );
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
 #endif /* _GPXE_RETRY_H */
51
 #endif /* _GPXE_RETRY_H */

+ 2
- 5
src/net/netdevice.c View File

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

+ 4
- 6
src/net/retry.c View File

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

Loading…
Cancel
Save