[syslinux:lwip] pxe: use a separate poll thread instead of using an idle thread hook

syslinux-bot for H. Peter Anvin hpa at zytor.com
Sun Apr 24 21:03:26 PDT 2011


Commit-ID:  f180d7c8ec74e0e15f1bcdf25c51899e2ca811c3
Gitweb:     http://syslinux.zytor.com/commit/f180d7c8ec74e0e15f1bcdf25c51899e2ca811c3
Author:     H. Peter Anvin <hpa at zytor.com>
AuthorDate: Sun, 24 Apr 2011 20:55:47 -0700
Committer:  H. Peter Anvin <hpa at zytor.com>
CommitDate: Sun, 24 Apr 2011 21:00:19 -0700

pxe: use a separate poll thread instead of using an idle thread hook

The idle thread can never sleep, so it's not really safe to do
anything inside it.  Instead, run a separate poll thread at low
priority; we can also do that to poll the serial console if needed.

Overall, the "classic" Syslinux idle handling really should go away
and be replaced by the idle thread.

Signed-off-by: H. Peter Anvin <hpa at zytor.com>


---
 core/fs/pxe/isr.c         |   46 ++++++++++++++++++++++++++------------------
 core/fs/pxe/pxe.c         |   10 ++++----
 core/fs/pxe/pxe.h         |    2 +-
 core/include/thread.h     |    9 ++++++-
 core/thread/idle_thread.c |    9 +------
 5 files changed, 42 insertions(+), 34 deletions(-)

diff --git a/core/fs/pxe/isr.c b/core/fs/pxe/isr.c
index ade3b0d..1df758c 100644
--- a/core/fs/pxe/isr.c
+++ b/core/fs/pxe/isr.c
@@ -12,7 +12,7 @@
 
 extern uint8_t pxe_irq_pending;
 static DECLARE_INIT_SEMAPHORE(pxe_receive_thread_sem, 0);
-static struct thread *pxe_thread;
+static struct thread *pxe_thread, *poll_thread;
 
 bool install_irq_vector(uint8_t irq, void (*isr)(void), far_ptr_t *old)
 {
@@ -72,16 +72,6 @@ static void pxe_poll_wakeups(void)
     }
 }
 
-static bool pxe_isr_poll(void)
-{
-    static __lowmem t_PXENV_UNDI_ISR isr;
-
-    isr.FuncFlag = PXENV_UNDI_ISR_IN_START;
-    pxe_call(PXENV_UNDI_ISR, &isr);
-
-    return isr.FuncFlag == PXENV_UNDI_ISR_OUT_OURS;
-}
-
 static void pxe_process_irq(void)
 {
     static __lowmem t_PXENV_UNDI_ISR isr;
@@ -128,14 +118,29 @@ static void pxe_receive_thread(void *dummy)
 
     for (;;) {
 	sem_down(&pxe_receive_thread_sem, 0);
-	if (pxe_irq_vector || pxe_isr_poll())
-	    pxe_process_irq();
+	pxe_process_irq();
     }
 }
 
-static void pxe_do_isr_poll(void)
+static bool pxe_isr_poll(void)
 {
-    sem_up(&pxe_receive_thread_sem);
+    static __lowmem t_PXENV_UNDI_ISR isr;
+
+    isr.FuncFlag = PXENV_UNDI_ISR_IN_START;
+    pxe_call(PXENV_UNDI_ISR, &isr);
+
+    return isr.FuncFlag == PXENV_UNDI_ISR_OUT_OURS;
+}
+
+static void pxe_poll_thread(void *dummy)
+{
+    (void)dummy;
+
+    for (;;) {
+	thread_yield();
+	if (pxe_isr_poll())
+	    sem_up(&pxe_receive_thread_sem);
+    }
 }
 
 void pxe_init_isr(void)
@@ -153,8 +158,9 @@ void pxe_init_isr(void)
     core_pm_hook = __schedule;
 
     if (!pxe_irq_vector) {
-	/* No IRQ vector, need to poll */
-	idle_hook = pxe_do_isr_poll;
+	/* No IRQ vector, need to poll. */
+	poll_thread = start_thread("pxe poll", 4096, POLL_THREAD_PRIORITY,
+				   pxe_poll_thread, NULL);
     }
 }
 
@@ -163,12 +169,14 @@ void pxe_cleanup_isr(void)
 {
     static __lowmem struct s_PXENV_UNDI_CLOSE undi_close;
 
-    idle_hook = NULL;
     sched_hook_func = NULL;
     core_pm_hook = core_pm_null_hook;
     kill_thread(pxe_thread);
 
     memset(&undi_close, 0, sizeof(undi_close));
     pxe_call(PXENV_UNDI_CLOSE, &undi_close);
-    uninstall_irq_vector(pxe_irq_vector, pxe_isr, &pxe_irq_chain);
+    if (pxe_irq_vector)
+	uninstall_irq_vector(pxe_irq_vector, pxe_isr, &pxe_irq_chain);
+    else
+	kill_thread(poll_thread);
 }
diff --git a/core/fs/pxe/pxe.c b/core/fs/pxe/pxe.c
index 2bcb27f..858f573 100644
--- a/core/fs/pxe/pxe.c
+++ b/core/fs/pxe/pxe.c
@@ -378,7 +378,7 @@ static void __pxe_searchdir(const char *filename, struct file *file)
     struct fs_info *fs = file->fs;
     struct inode *inode;
     char fullpath[2*FILENAME_MAX];
-#ifdef GPXE
+#if GPXE
     char urlsave[2*FILENAME_MAX];
 #endif
     struct url_info url;
@@ -393,13 +393,13 @@ static void __pxe_searchdir(const char *filename, struct file *file)
 	    break;
 
 	strlcpy(fullpath, filename, sizeof fullpath);
-#ifdef GPXE
+#if GPXE
 	strcpy(urlsave, fullpath);
 #endif
 	parse_url(&url, fullpath);
 	if (url.type == URL_SUFFIX) {
 	    snprintf(fullpath, sizeof fullpath, "%s%s", fs->cwd_name, filename);
-#ifdef GPXE
+#if GPXE
 	    strcpy(urlsave, fullpath);
 #endif
 	    parse_url(&url, fullpath);
@@ -424,12 +424,12 @@ static void __pxe_searchdir(const char *filename, struct file *file)
 	/* filename here is set on a redirect */
     }
 
-#ifdef GPXE
     if (!found_scheme) {
+#if GPXE
 	/* No URL scheme found, hand it to GPXE */
 	gpxe_open(inode, urlsave);
-    }
 #endif
+    }
 
     if (inode->size)
 	file->inode = inode;
diff --git a/core/fs/pxe/pxe.h b/core/fs/pxe/pxe.h
index a685d8e..24a8642 100644
--- a/core/fs/pxe/pxe.h
+++ b/core/fs/pxe/pxe.h
@@ -242,7 +242,7 @@ void tftp_open(struct url_info *url, struct inode *inode, const char **redir);
 
 /* gpxeurl.c */
 void gpxe_open(struct inode *inode, const char *url);
-#define GPXE 1
+#define GPXE 0
 
 /* http.c */
 void http_open(struct url_info *url, struct inode *inode, const char **redir);
diff --git a/core/include/thread.h b/core/include/thread.h
index 7c83b5a..be3844a 100644
--- a/core/include/thread.h
+++ b/core/include/thread.h
@@ -3,9 +3,16 @@
 
 #include <stddef.h>
 #include <inttypes.h>
+#include <limits.h>
 #include <stdbool.h>
 #include <timer.h>
 
+/* The idle thread runs at this priority */
+#define IDLE_THREAD_PRIORITY	INT_MAX
+
+/* This priority should normally be used for hardware-polling threads */
+#define POLL_THREAD_PRIORITY	(INT_MAX-1)
+
 struct semaphore;
 
 struct thread_list {
@@ -95,6 +102,4 @@ void kill_thread(struct thread *);
 void start_idle_thread(void);
 void test_thread(void);
 
-extern void (*idle_hook)(void);
-
 #endif /* _THREAD_H */
diff --git a/core/thread/idle_thread.c b/core/thread/idle_thread.c
index e2f8b57..a3a5be2 100644
--- a/core/thread/idle_thread.c
+++ b/core/thread/idle_thread.c
@@ -2,8 +2,6 @@
 #include <limits.h>
 #include <sys/cpu.h>
 
-void (*idle_hook)(void);
-
 static void idle_thread_func(void *dummy)
 {
     (void)dummy;
@@ -11,15 +9,12 @@ static void idle_thread_func(void *dummy)
 
     for (;;) {
 	thread_yield();
-	if (idle_hook)
-	    idle_hook();
-	else
-	    asm volatile("hlt");
+	asm volatile("hlt");
     }
 }
 
 void start_idle_thread(void)
 {
-    start_thread("idle", 4096, INT_MAX, idle_thread_func, NULL);
+    start_thread("idle", 4096, IDLE_THREAD_PRIORITY, idle_thread_func, NULL);
 }
 



More information about the Syslinux-commits mailing list