summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2010-06-17 20:15:58 +0000
committerMichael Sevakis <jethead71@rockbox.org>2010-06-17 20:15:58 +0000
commit2b640ba4b8a0007821677fc9f3cf9e856d53417e (patch)
treeb68204a1c5a33a93980a7903bc5cb4a906af5938
parent69028d5d31384a0a97bd42081cacb01eb5d52793 (diff)
downloadrockbox-2b640ba4b8a0007821677fc9f3cf9e856d53417e.tar.gz
rockbox-2b640ba4b8a0007821677fc9f3cf9e856d53417e.zip
Switch iPod 3G to use EABI toolchain. Make necessary threading changes to avoid use of stack after switching to idle stack.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26898 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/main.c6
-rw-r--r--firmware/export/thread.h2
-rw-r--r--firmware/target/hosted/sdl/thread-sdl.c5
-rw-r--r--firmware/thread.c72
-rwxr-xr-xtools/configure2
5 files changed, 54 insertions, 33 deletions
diff --git a/apps/main.c b/apps/main.c
index 858ec03847..2555deb12f 100644
--- a/apps/main.c
+++ b/apps/main.c
@@ -694,7 +694,7 @@ static void init(void)
694} 694}
695 695
696#ifdef CPU_PP 696#ifdef CPU_PP
697void cop_main(void) 697void __attribute__((noreturn)) cop_main(void)
698{ 698{
699/* This is the entry point for the coprocessor 699/* This is the entry point for the coprocessor
700 Anyone not running an upgraded bootloader will never reach this point, 700 Anyone not running an upgraded bootloader will never reach this point,
@@ -705,7 +705,6 @@ void cop_main(void)
705 destroyed for purposes of continuity. The cop sits idle until at least 705 destroyed for purposes of continuity. The cop sits idle until at least
706 one thread exists on it. */ 706 one thread exists on it. */
707 707
708/* 3G doesn't have Rolo or dual core support yet */
709#if NUM_CORES > 1 708#if NUM_CORES > 1
710 system_init(); 709 system_init();
711 kernel_init(); 710 kernel_init();
@@ -717,5 +716,4 @@ void cop_main(void)
717} 716}
718#endif /* CPU_PP */ 717#endif /* CPU_PP */
719 718
720#endif 719#endif /* SIMULATOR */
721
diff --git a/firmware/export/thread.h b/firmware/export/thread.h
index 8912283343..d907e5dc95 100644
--- a/firmware/export/thread.h
+++ b/firmware/export/thread.h
@@ -375,7 +375,7 @@ void thread_thaw(unsigned int thread_id);
375/* Wait for a thread to exit */ 375/* Wait for a thread to exit */
376void thread_wait(unsigned int thread_id); 376void thread_wait(unsigned int thread_id);
377/* Exit the current thread */ 377/* Exit the current thread */
378void thread_exit(void); 378void thread_exit(void) __attribute__((noreturn));
379#if defined(DEBUG) || defined(ROCKBOX_HAS_LOGF) 379#if defined(DEBUG) || defined(ROCKBOX_HAS_LOGF)
380#define ALLOW_REMOVE_THREAD 380#define ALLOW_REMOVE_THREAD
381/* Remove a thread from the scheduler */ 381/* Remove a thread from the scheduler */
diff --git a/firmware/target/hosted/sdl/thread-sdl.c b/firmware/target/hosted/sdl/thread-sdl.c
index 5ef9867b23..1a683911d7 100644
--- a/firmware/target/hosted/sdl/thread-sdl.c
+++ b/firmware/target/hosted/sdl/thread-sdl.c
@@ -630,6 +630,11 @@ void remove_thread(unsigned int thread_id)
630void thread_exit(void) 630void thread_exit(void)
631{ 631{
632 remove_thread(THREAD_ID_CURRENT); 632 remove_thread(THREAD_ID_CURRENT);
633 /* This should never and must never be reached - if it is, the
634 * state is corrupted */
635 THREAD_PANICF("thread_exit->K:*R",
636 thread_id_entry(THREAD_ID_CURRENT));
637 while (1);
633} 638}
634 639
635void thread_wait(unsigned int thread_id) 640void thread_wait(unsigned int thread_id)
diff --git a/firmware/thread.c b/firmware/thread.c
index 5cad67b657..48734f2ffe 100644
--- a/firmware/thread.c
+++ b/firmware/thread.c
@@ -156,6 +156,14 @@ static inline void store_context(void* addr)
156static inline void load_context(const void* addr) 156static inline void load_context(const void* addr)
157 __attribute__((always_inline)); 157 __attribute__((always_inline));
158 158
159#if NUM_CORES > 1
160static void __attribute__((noinline, noreturn))
161 thread_final_exit(struct thread_entry *current);
162#else
163static void __attribute__((always_inline, noreturn))
164 thread_final_exit(struct thread_entry *current);
165#endif
166
159void switch_thread(void) 167void switch_thread(void)
160 __attribute__((noinline)); 168 __attribute__((noinline));
161 169
@@ -219,7 +227,7 @@ static void thread_stkov(struct thread_entry *thread)
219#define LOCK_THREAD(thread) \ 227#define LOCK_THREAD(thread) \
220 ({ corelock_lock(&(thread)->slot_cl); }) 228 ({ corelock_lock(&(thread)->slot_cl); })
221#define TRY_LOCK_THREAD(thread) \ 229#define TRY_LOCK_THREAD(thread) \
222 ({ corelock_try_lock(&thread->slot_cl); }) 230 ({ corelock_try_lock(&(thread)->slot_cl); })
223#define UNLOCK_THREAD(thread) \ 231#define UNLOCK_THREAD(thread) \
224 ({ corelock_unlock(&(thread)->slot_cl); }) 232 ({ corelock_unlock(&(thread)->slot_cl); })
225#define UNLOCK_THREAD_AT_TASK_SWITCH(thread) \ 233#define UNLOCK_THREAD_AT_TASK_SWITCH(thread) \
@@ -854,7 +862,8 @@ struct thread_entry *
854 * catch something. 862 * catch something.
855 *--------------------------------------------------------------------------- 863 *---------------------------------------------------------------------------
856 */ 864 */
857static void check_for_obj_waiters(const char *function, struct thread_entry *thread) 865static void __attribute__((noinline)) check_for_obj_waiters(
866 const char *function, struct thread_entry *thread)
858{ 867{
859 /* Only one bit in the mask should be set with a frequency on 1 which 868 /* Only one bit in the mask should be set with a frequency on 1 which
860 * represents the thread's own base priority */ 869 * represents the thread's own base priority */
@@ -1663,10 +1672,39 @@ void thread_wait(unsigned int thread_id)
1663 * Exit the current thread. The Right Way to Do Things (TM). 1672 * Exit the current thread. The Right Way to Do Things (TM).
1664 *--------------------------------------------------------------------------- 1673 *---------------------------------------------------------------------------
1665 */ 1674 */
1675/* This is done to foil optimizations that may require the current stack,
1676 * such as optimizing subexpressions that put variables on the stack that
1677 * get used after switching stacks. */
1678static void thread_final_exit(struct thread_entry *current)
1679{
1680#if NUM_CORES > 1
1681 cpucache_flush();
1682
1683 /* Switch to the idle stack if not on the main core (where "main"
1684 * runs) - we can hope gcc doesn't need the old stack beyond this
1685 * point. */
1686 if (current->core != CPU)
1687 {
1688 switch_to_idle_stack(current->core);
1689 }
1690
1691 /* At this point, this thread isn't using resources allocated for
1692 * execution except the slot itself. */
1693#endif /* NUM_CORES */
1694
1695 /* Signal this thread */
1696 thread_queue_wake(&current->queue);
1697 corelock_unlock(&current->waiter_cl);
1698 switch_thread();
1699 /* This should never and must never be reached - if it is, the
1700 * state is corrupted */
1701 THREAD_PANICF("thread_exit->K:*R", current);
1702 while (1);
1703}
1704
1666void thread_exit(void) 1705void thread_exit(void)
1667{ 1706{
1668 const unsigned int core = CURRENT_CORE; 1707 register struct thread_entry * current = cores[CURRENT_CORE].running;
1669 struct thread_entry *current = cores[core].running;
1670 1708
1671 /* Cancel CPU boost if any */ 1709 /* Cancel CPU boost if any */
1672 cancel_cpu_boost(); 1710 cancel_cpu_boost();
@@ -1701,34 +1739,14 @@ void thread_exit(void)
1701 /* Switch tasks and never return */ 1739 /* Switch tasks and never return */
1702 block_thread_on_l(current, STATE_KILLED); 1740 block_thread_on_l(current, STATE_KILLED);
1703 1741
1704#if NUM_CORES > 1 1742 /* Slot must be unusable until thread is really gone */
1705 /* Switch to the idle stack if not on the main core (where "main" 1743 UNLOCK_THREAD_AT_TASK_SWITCH(current);
1706 * runs) - we can hope gcc doesn't need the old stack beyond this
1707 * point. */
1708 if (core != CPU)
1709 {
1710 switch_to_idle_stack(core);
1711 }
1712
1713 cpucache_flush();
1714
1715 /* At this point, this thread isn't using resources allocated for
1716 * execution except the slot itself. */
1717#endif
1718 1744
1719 /* Update ID for this slot */ 1745 /* Update ID for this slot */
1720 new_thread_id(current->id, current); 1746 new_thread_id(current->id, current);
1721 current->name = NULL; 1747 current->name = NULL;
1722 1748
1723 /* Signal this thread */ 1749 thread_final_exit(current);
1724 thread_queue_wake(&current->queue);
1725 corelock_unlock(&current->waiter_cl);
1726 /* Slot must be unusable until thread is really gone */
1727 UNLOCK_THREAD_AT_TASK_SWITCH(current);
1728 switch_thread();
1729 /* This should never and must never be reached - if it is, the
1730 * state is corrupted */
1731 THREAD_PANICF("thread_exit->K:*R", current);
1732} 1750}
1733 1751
1734#ifdef ALLOW_REMOVE_THREAD 1752#ifdef ALLOW_REMOVE_THREAD
diff --git a/tools/configure b/tools/configure
index 3503f8493c..c805f2250e 100755
--- a/tools/configure
+++ b/tools/configure
@@ -40,7 +40,7 @@ prefixtools () {
40} 40}
41 41
42findarmgcc() { 42findarmgcc() {
43 models_not_checked_with_eabi="ipodnano1g ipod3g ipod4g ipodmini1g ipod1g2g vibe500 cowond2" 43 models_not_checked_with_eabi="ipodnano1g ipod4g ipodmini1g ipod1g2g vibe500 cowond2"
44 if [ "$ARG_ARM_EABI" != 1 ]; then # eabi not explicitely enabled 44 if [ "$ARG_ARM_EABI" != 1 ]; then # eabi not explicitely enabled
45 for model in $models_not_checked_with_eabi; do 45 for model in $models_not_checked_with_eabi; do
46 if [ "$modelname" = "$model" ]; then 46 if [ "$modelname" = "$model" ]; then