[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