1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
diff --git a/apps/misc.c b/apps/misc.c
index e049663..b2f1df5 100644
--- a/apps/misc.c
+++ b/apps/misc.c
@@ -26,7 +26,6 @@
 #include "string-extra.h"
 #include "config.h"
 #include "misc.h"
-#include "system.h"
 #include "lcd.h"
 #include "file.h"
 #include "filefuncs.h"
diff --git a/apps/misc.h b/apps/misc.h
index 1022af4..fa66956 100644
--- a/apps/misc.h
+++ b/apps/misc.h
@@ -24,6 +24,7 @@
 #include <stdbool.h>
 #include <inttypes.h>
 #include "config.h"
+#include "system.h"
 #include "screen_access.h"

 extern const unsigned char * const byte_units[];
diff --git a/apps/radio/radioart.c b/apps/radio/radioart.c
index 23fb7a3..85397c1 100644
--- a/apps/radio/radioart.c
+++ b/apps/radio/radioart.c
@@ -23,13 +23,13 @@
 #include <stdio.h>
 #include <stdbool.h>
 #include <stdlib.h>
-#include "system.h"
 #include "settings.h"
 #include "radio.h"
 #include "buffering.h"
 #include "file.h"
 #include "kernel.h"
 #include "string-extra.h"
+#include "misc.h"
 #include "filefuncs.h"

 #define MAX_RADIOART_IMAGES 10
diff --git a/firmware/SOURCES b/firmware/SOURCES
index b2b353b..9c9ebf5 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -37,11 +37,7 @@ target/hosted/sdl/lcd-remote-bitmap.c
 #endif
 target/hosted/sdl/lcd-sdl.c
 target/hosted/sdl/system-sdl.c
-#ifdef HAVE_SDL_THREADS
 target/hosted/sdl/thread-sdl.c
-#else
-thread.c
-#endif
 target/hosted/sdl/timer-sdl.c
 #ifdef HAVE_TOUCHSCREEN
 target/hosted/sdl/key_to_touch-sdl.c
diff --git a/firmware/export/config.h b/firmware/export/config.h
index a870e5d..3063e1f 100644
--- a/firmware/export/config.h
+++ b/firmware/export/config.h
@@ -717,9 +717,7 @@ Lyre prototype 1 */
 #define HAVE_WAKEUP_EXT_CB


-#if defined(ASSEMBLER_THREADS) \
-    || defined(HAVE_WIN32_FIBER_THREADS) \
-    || defined(HAVE_SIGALTSTACK_THREADS)
+#if (CONFIG_PLATFORM & PLATFORM_ANDROID)
 #define HAVE_PRIORITY_SCHEDULING
 #endif

diff --git a/firmware/export/thread.h b/firmware/export/thread.h
index 179979a..3cce784 100644
--- a/firmware/export/thread.h
+++ b/firmware/export/thread.h
@@ -84,19 +84,15 @@
  * We need more stack when we run under a host
  * maybe more expensive C lib functions?
  *
- * simulator (possibly) doesn't simulate stack usage anyway but well ... */
-#ifdef HAVE_SIGALTSTACK_THREADS
-#include <signal.h>
-/* MINSIGSTKSZ for the OS to deliver the signal + 0x3000 for us */
-#define DEFAULT_STACK_SIZE (MINSIGSTKSZ+0x3000) /* Bytes */
-#elif (CONFIG_PLATFORM & PLATFORM_ANDROID) || defined(HAVE_WIN32_FIBER_THREADS)
-#define DEFAULT_STACK_SIZE 0x1000 /* Bytes */
-#else /* native threads, sdl threads */
+ * simulator doesn't simulate stack usage anyway but well ... */
+#if ((CONFIG_PLATFORM & PLATFORM_NATIVE) || defined(SIMULATOR))
 #define DEFAULT_STACK_SIZE 0x400 /* Bytes */
+#else
+#define DEFAULT_STACK_SIZE 0x1000 /* Bytes */
 #endif


-#if defined(ASSEMBLER_THREADS)
+#if (CONFIG_PLATFORM & (PLATFORM_NATIVE|PLATFORM_ANDROID))
 /* Need to keep structures inside the header file because debug_menu
  * needs them. */
 #ifdef CPU_COLDFIRE
@@ -116,7 +112,7 @@ struct regs
     uint32_t pr;    /*    32 - Procedure register */
     uint32_t start; /*    36 - Thread start address, or NULL when started */
 };
-#elif defined(CPU_ARM)
+#elif defined(CPU_ARM) || (CONFIG_PLATFORM & PLATFORM_ANDROID)
 struct regs
 {
     uint32_t r[8];  /*  0-28 - Registers r4-r11 */
@@ -125,6 +121,22 @@ struct regs
     uint32_t start; /*    40 - Thread start address, or NULL when started */
 };

+#ifdef CPU_PP
+#ifdef HAVE_CORELOCK_OBJECT
+/* No reliable atomic instruction available - use Peterson's algorithm */
+struct corelock
+{
+    volatile unsigned char myl[NUM_CORES];
+    volatile unsigned char turn;
+} __attribute__((packed));
+
+/* Too big to inline everywhere */
+void corelock_init(struct corelock *cl);
+void corelock_lock(struct corelock *cl);
+int corelock_try_lock(struct corelock *cl);
+void corelock_unlock(struct corelock *cl);
+#endif /* HAVE_CORELOCK_OBJECT */
+#endif /* CPU_PP */
 #elif defined(CPU_MIPS)
 struct regs
 {
@@ -134,17 +146,7 @@ struct regs
     uint32_t start; /*   44 - Thread start address, or NULL when started */
 };
 #endif /* CONFIG_CPU */
-#elif (CONFIG_PLATFORM & PLATFORM_HOSTED) || defined(__PCTOOL__)
-#ifndef HAVE_SDL_THREADS
-struct regs
-{
-    void (*start)(void); /* thread's entry point, or NULL when started */
-    void* uc;            /* host thread handle */
-    uintptr_t sp;        /* Stack pointer, unused */
-    size_t stack_size;   /* stack size, not always used */
-    uintptr_t stack;     /* pointer to start of the stack buffer */
-};
-#else /* SDL threads */
+#elif (CONFIG_PLATFORM & PLATFORM_HOSTED)
 struct regs
 {
     void *t;             /* OS thread */
@@ -152,26 +154,8 @@ struct regs
     void *s;             /* Semaphore for blocking and wakeup */
     void (*start)(void); /* Start function */
 };
-#endif
 #endif /* PLATFORM_NATIVE */

-#ifdef CPU_PP
-#ifdef HAVE_CORELOCK_OBJECT
-/* No reliable atomic instruction available - use Peterson's algorithm */
-struct corelock
-{
-    volatile unsigned char myl[NUM_CORES];
-    volatile unsigned char turn;
-} __attribute__((packed));
-
-/* Too big to inline everywhere */
-void corelock_init(struct corelock *cl);
-void corelock_lock(struct corelock *cl);
-int corelock_try_lock(struct corelock *cl);
-void corelock_unlock(struct corelock *cl);
-#endif /* HAVE_CORELOCK_OBJECT */
-#endif /* CPU_PP */
-
 /* NOTE: The use of the word "queue" may also refer to a linked list of
    threads being maintained that are normally dealt with in FIFO order
    and not necessarily kernel event_queue */
@@ -267,7 +251,7 @@ struct thread_entry
                                   object where thread is blocked - used
                                   for implicit unblock and explicit wake
                                   states: STATE_BLOCKED/STATE_BLOCKED_W_TMO  */
-#ifdef HAVE_CORELOCK_OBJECT
+#if NUM_CORES > 1
     struct corelock *obj_cl;   /* Object corelock where thead is blocked -
                                   states: STATE_BLOCKED/STATE_BLOCKED_W_TMO */
     struct corelock waiter_cl; /* Corelock for thread_wait */
@@ -324,7 +308,7 @@ struct thread_entry
 /* Specify current thread in a function taking an ID. */
 #define THREAD_ID_CURRENT ((unsigned int)-1)

-#ifdef HAVE_CORELOCK_OBJECT
+#if NUM_CORES > 1
 /* Operations to be performed just before stopping a thread and starting
    a new one if specified before calling switch_thread */
 enum
@@ -357,7 +341,7 @@ struct core_entry
                                          threads */
 #endif
     long next_tmo_check;           /* soonest time to check tmo threads */
-#ifdef HAVE_CORELOCK_OBJECT
+#if NUM_CORES > 1
     struct thread_blk_ops blk_ops; /* operations to perform when
                                       blocking a thread */
     struct corelock rtr_cl;        /* Lock for rtr list */
diff --git a/firmware/kernel.c b/firmware/kernel.c
index 588bbd2..ee42574 100644
--- a/firmware/kernel.c
+++ b/firmware/kernel.c
@@ -68,9 +68,7 @@ void (*tick_funcs[MAX_NUM_TICK_TASKS+1])(void);
 static struct
 {
     struct event_queue *queues[MAX_NUM_QUEUES+1];
-#ifdef HAVE_CORELOCK_OBJECT
-    struct corelock cl;
-#endif
+    IF_COP( struct corelock cl; )
 } all_queues SHAREDBSS_ATTR;

 /****************************************************************************
diff --git a/firmware/target/hosted/android/thread-android-arm.c b/firmware/target/hosted/android/thread-android-arm.c
new file mode 100644
index 0000000..0bfd2b6
--- /dev/null
+++ b/firmware/target/hosted/android/thread-android-arm.c
@@ -0,0 +1,98 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2005 by Thom Johansen
+ * Copyright (C) 2010 by Thomas Martitz (Android-suitable core_sleep())
+ *
+ * Generic ARM threading support
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include <jni.h>
+#include <system.h>
+/*---------------------------------------------------------------------------
+ * Start the thread running and terminate it if it returns
+ *---------------------------------------------------------------------------
+ */
+static void __attribute__((naked,used)) start_thread(void)
+{
+    /* r0 = context */
+    asm volatile (
+        "ldr    sp, [r0, #32]            \n" /* Load initial sp */
+        "ldr    r4, [r0, #40]            \n" /* start in r4 since it's non-volatile */
+        "mov    r1, #0                   \n" /* Mark thread as running */
+        "str    r1, [r0, #40]            \n"
+        "mov    lr, pc                   \n" /* Call thread function */
+        "bx     r4                       \n"
+    ); /* No clobber list - new thread doesn't care */
+    thread_exit();
+}
+
+/* For startup, place context pointer in r4 slot, start_thread pointer in r5
+ * slot, and thread function pointer in context.start. See load_context for
+ * what happens when thread is initially going to run. */
+#define THREAD_STARTUP_INIT(core, thread, function) \
+    ({ (thread)->context.r[0] = (uint32_t)&(thread)->context,  \
+       (thread)->context.r[1] = (uint32_t)start_thread, \
+       (thread)->context.start = (uint32_t)function; })
+
+
+/*---------------------------------------------------------------------------
+ * Store non-volatile context.
+ *---------------------------------------------------------------------------
+ */
+static inline void store_context(void* addr)
+{
+    asm volatile(
+        "stmia  %0, { r4-r11, sp, lr } \n"
+        : : "r" (addr)
+    );
+}
+
+/*---------------------------------------------------------------------------
+ * Load non-volatile context.
+ *---------------------------------------------------------------------------
+ */
+static inline void load_context(const void* addr)
+{
+    asm volatile(
+        "ldr     r0, [%0, #40]          \n" /* Load start pointer */
+        "cmp     r0, #0                 \n" /* Check for NULL */
+
+        /* If not already running, jump to start */
+        "ldmneia %0, { r0, pc }         \n"
+        "ldmia   %0, { r4-r11, sp, lr } \n" /* Load regs r4 to r14 from context */
+        : : "r" (addr) : "r0" /* only! */
+    );
+}
+
+/*
+ * this core sleep suspends the OS thread rockbox runs under, which greatly
+ * reduces cpu usage (~100% to <10%)
+ *
+ * it returns when the RockboxTimer notified us, i.e. at each tick
+ * (after it called the tick tasks)
+ *
+ * wait_for_interrupt is implemented in kernel-android.c
+ **/
+
+static inline void core_sleep(void)
+{
+    wait_for_interrupt();
+}
+
+
diff --git a/firmware/target/hosted/sdl/button-sdl.c b/firmware/target/hosted/sdl/button-sdl.c
index 9f1c1f7..7abe2ae 100644
--- a/firmware/target/hosted/sdl/button-sdl.c
+++ b/firmware/target/hosted/sdl/button-sdl.c
@@ -28,7 +28,7 @@
 #include "button.h"
 #include "kernel.h"
 #include "backlight.h"
-#include "system.h"
+#include "misc.h"
 #include "button-sdl.h"
 #include "backlight.h"
 #include "sim_tasks.h"
diff --git a/firmware/target/hosted/sdl/kernel-sdl.c b/firmware/target/hosted/sdl/kernel-sdl.c
index 4fb1aed..d933b90 100644
--- a/firmware/target/hosted/sdl/kernel-sdl.c
+++ b/firmware/target/hosted/sdl/kernel-sdl.c
@@ -34,14 +34,6 @@
 static SDL_TimerID tick_timer_id;
 long start_tick;

-#ifndef HAVE_SDL_THREADS
-/* for the wait_for_interrupt function */
-static bool do_exit;
-static SDL_cond *wfi_cond;
-static SDL_mutex *wfi_mutex;
-#else
-#define do_exit false
-#endif
 /* Condition to signal that "interrupts" may proceed */
 static SDL_cond *sim_thread_cond;
 /* Mutex to serialize changing levels and exclude other threads while
@@ -106,9 +98,6 @@ void sim_exit_irq_handler(void)

     status_reg = 0;
     SDL_UnlockMutex(sim_irq_mtx);
-#ifndef HAVE_SDL_THREADS
-    SDL_CondSignal(wfi_cond);
-#endif
 }

 static bool sim_kernel_init(void)
@@ -126,33 +115,15 @@ static bool sim_kernel_init(void)
         panicf("Cannot create sim_thread_cond\n");
         return false;
     }
-#ifndef HAVE_SDL_THREADS
-    wfi_cond = SDL_CreateCond();
-    if (wfi_cond == NULL)
-    {
-        panicf("Cannot create wfi\n");
-        return false;
-    }
-    wfi_mutex = SDL_CreateMutex();
-    if (wfi_mutex == NULL)
-    {
-        panicf("Cannot create wfi mutex\n");
-        return false;
-    }
-#endif
+
     return true;
 }

 void sim_kernel_shutdown(void)
 {
     SDL_RemoveTimer(tick_timer_id);
-#ifndef HAVE_SDL_THREADS
-    do_exit = true;
-    SDL_CondSignal(wfi_cond);
-#endif
-    disable_irq(); 
     SDL_DestroyMutex(sim_irq_mtx);
-    SDL_DestroyCond(sim_thread_cond); 
+    SDL_DestroyCond(sim_thread_cond);
 }

 Uint32 tick_timer(Uint32 interval, void *param)
@@ -164,7 +135,7 @@ Uint32 tick_timer(Uint32 interval, void *param)

     new_tick = (SDL_GetTicks() - start_tick) / (1000/HZ);

-    while(new_tick != current_tick && !do_exit)
+    while(new_tick != current_tick)
     {
         sim_enter_irq_handler();

@@ -175,7 +146,7 @@ Uint32 tick_timer(Uint32 interval, void *param)
         sim_exit_irq_handler();
     }

-    return do_exit ? 0 : interval;
+    return interval;
 }

 void tick_start(unsigned int interval_in_ms)
@@ -197,29 +168,4 @@ void tick_start(unsigned int interval_in_ms)
     }

     tick_timer_id = SDL_AddTimer(interval_in_ms, tick_timer, NULL);
-#ifndef HAVE_SDL_THREADS
-    SDL_LockMutex(wfi_mutex);
-#endif
-}
-
-#ifndef HAVE_SDL_THREADS
-static void check_exit(void)
-{
-    if (UNLIKELY(do_exit))
-    {
-        SDL_DestroyCond(wfi_cond);
-        SDL_UnlockMutex(wfi_mutex);
-        SDL_DestroyMutex(wfi_mutex);
-        sim_do_exit();
-    }
-}
-
-void wait_for_interrupt(void)
-{
-    /* the exit may come at any time, during the CondWait or before,
-     * so check it twice */
-    check_exit();
-    SDL_CondWait(wfi_cond, wfi_mutex);
-    check_exit();
 }
-#endif
diff --git a/firmware/target/hosted/sdl/system-sdl.c b/firmware/target/hosted/sdl/system-sdl.c
index 1cc9b2c..9ea25c1 100644
--- a/firmware/target/hosted/sdl/system-sdl.c
+++ b/firmware/target/hosted/sdl/system-sdl.c
@@ -184,9 +184,7 @@ static int sdl_event_thread(void * param)

     /* Order here is relevent to prevent deadlocks and use of destroyed
        sync primitives by kernel threads */
-#ifdef HAVE_SDL_THREADS
-    sim_thread_shutdown(); /* not needed for native threads */
-#endif
+    sim_thread_shutdown();
     sim_kernel_shutdown();

     return 0;
@@ -201,13 +199,9 @@ void sim_do_exit(void)
     exit(EXIT_SUCCESS);
 }

-uintptr_t *stackbegin;
-uintptr_t *stackend;
 void system_init(void)
 {
     SDL_sem *s;
-    /* fake stack, OS manages size (and growth) */
-    stackbegin = stackend = (uintptr_t*)&s;

 #if (CONFIG_PLATFORM & PLATFORM_MAEMO)
     /* Make glib thread safe */
@@ -225,25 +219,22 @@ void system_init(void)
     /* wait for sdl_event_thread to run so that it can initialize the surfaces
      * and video subsystem needed for SDL events */
     SDL_SemWait(s);
+
     /* cleanup */
     SDL_DestroySemaphore(s);
 }

-
-void system_reboot(void)
+void system_exception_wait(void)
 {
-#ifdef HAVE_SDL_THREADS
     sim_thread_exception_wait();
-#else
-    sim_do_exit();
-#endif
 }

-void system_exception_wait(void)
+void system_reboot(void)
 {
-    system_reboot();
+    sim_thread_exception_wait();
 }

+
 void sys_handle_argv(int argc, char *argv[])
 {
     if (argc >= 1) 
diff --git a/firmware/target/hosted/sdl/system-sdl.h b/firmware/target/hosted/sdl/system-sdl.h
index bec01ec..01952e5 100644
--- a/firmware/target/hosted/sdl/system-sdl.h
+++ b/firmware/target/hosted/sdl/system-sdl.h
@@ -46,9 +46,6 @@ void sys_poweroff(void);
 void sys_handle_argv(int argc, char *argv[]);
 void gui_message_loop(void);
 void sim_do_exit(void);
-#ifndef HAVE_SDL_THREADS
-void wait_for_interrupt(void);
-#endif

 extern bool background;  /* True if the background image is enabled */
 extern bool showremote;
diff --git a/firmware/target/hosted/sdl/thread-sdl.h b/firmware/target/hosted/sdl/thread-sdl.h
index 9edb3ee..9384e60 100644
--- a/firmware/target/hosted/sdl/thread-sdl.h
+++ b/firmware/target/hosted/sdl/thread-sdl.h
@@ -22,13 +22,11 @@
 #ifndef __THREADSDL_H__
 #define __THREADSDL_H__

-#ifdef HAVE_SDL_THREADS
 /* extra thread functions that only apply when running on hosting platforms */
 void sim_thread_lock(void *me);
 void * sim_thread_unlock(void);
 void sim_thread_exception_wait(void);
 void sim_thread_shutdown(void); /* Shut down all kernel threads gracefully */
-#endif

 #endif /* #ifndef __THREADSDL_H__ */

diff --git a/firmware/target/hosted/thread-arm.c b/firmware/target/hosted/thread-arm.c
deleted file mode 100644
index d2fa7d1..0000000
--- a/firmware/target/hosted/thread-arm.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2005 by Thom Johansen
- * Copyright (C) 2010 by Thomas Martitz (Android-suitable core_sleep())
- *
- * Generic ARM threading support
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-
-#include <system.h>
-/*---------------------------------------------------------------------------
- * Start the thread running and terminate it if it returns
- *---------------------------------------------------------------------------
- */
-static void __attribute__((naked,used)) start_thread(void)
-{
-    /* r0 = context */
-    asm volatile (
-        "ldr    sp, [r0, #32]            \n" /* Load initial sp */
-        "ldr    r4, [r0, #40]            \n" /* start in r4 since it's non-volatile */
-        "mov    r1, #0                   \n" /* Mark thread as running */
-        "str    r1, [r0, #40]            \n"
-        "mov    lr, pc                   \n" /* Call thread function */
-        "bx     r4                       \n"
-    ); /* No clobber list - new thread doesn't care */
-    thread_exit();
-}
-
-/* For startup, place context pointer in r4 slot, start_thread pointer in r5
- * slot, and thread function pointer in context.start. See load_context for
- * what happens when thread is initially going to run. */
-#define THREAD_STARTUP_INIT(core, thread, function) \
-    ({ (thread)->context.r[0] = (uint32_t)&(thread)->context,  \
-       (thread)->context.r[1] = (uint32_t)start_thread, \
-       (thread)->context.start = (uint32_t)function; })
-
-
-/*---------------------------------------------------------------------------
- * Store non-volatile context.
- *---------------------------------------------------------------------------
- */
-static inline void store_context(void* addr)
-{
-    asm volatile(
-        "stmia  %0, { r4-r11, sp, lr } \n"
-        : : "r" (addr)
-    );
-}
-
-/*---------------------------------------------------------------------------
- * Load non-volatile context.
- *---------------------------------------------------------------------------
- */
-static inline void load_context(const void* addr)
-{
-    asm volatile(
-        "ldr     r0, [%0, #40]          \n" /* Load start pointer */
-        "cmp     r0, #0                 \n" /* Check for NULL */
-
-        /* If not already running, jump to start */
-        "ldmneia %0, { r0, pc }         \n"
-        "ldmia   %0, { r4-r11, sp, lr } \n" /* Load regs r4 to r14 from context */
-        : : "r" (addr) : "r0" /* only! */
-    );
-}
-
-/*
- * this core sleep suspends the OS thread rockbox runs under, which greatly
- * reduces cpu usage (~100% to <10%)
- *
- * it returns when when the tick timer is called, other interrupt-like
- * events occur
- *
- * wait_for_interrupt is implemented in kernel-<platform>.c
- **/
-
-static inline void core_sleep(void)
-{
-    enable_irq();
-    wait_for_interrupt();
-}
-
-
diff --git a/firmware/target/hosted/thread-unix.c b/firmware/target/hosted/thread-unix.c
deleted file mode 100644
index a84ac70..0000000
--- a/firmware/target/hosted/thread-unix.c
+++ /dev/null
@@ -1,294 +0,0 @@
-#include <stdlib.h>
-#include <stdbool.h>
-#include <signal.h>
-#include <stdio.h>
-#include <setjmp.h>
-#include <unistd.h>
-#include <pthread.h>
-#include <errno.h>
-#include "debug.h"
-
-static volatile bool sig_handler_called;
-static volatile jmp_buf tramp_buf;
-static volatile jmp_buf bootstrap_buf;
-static void (*thread_func)(void);
-static const int trampoline_sig = SIGUSR1;
-static pthread_t main_thread;
-
-static struct ctx {
-    jmp_buf thread_buf;
-} thread_bufs[MAXTHREADS];
-static struct ctx* thread_context, *target_context;
-static int curr_uc;
-
-static void trampoline(int sig);
-static void bootstrap_context(void) __attribute__((noinline));
-
-/* The *_context functions are heavily based on Gnu pth
- * http://www.gnu.org/software/pth/
- *
- * adjusted to work in a multi-thread environment to
- * offer a ucontext-like API
- */
-
-/*
- * VARIANT 2: THE SIGNAL STACK TRICK
- *
- * This uses sigstack/sigaltstack() and friends and is really the
- * most tricky part of Pth. When you understand the following
- * stuff you're a good Unix hacker and then you've already
- * understood the gory ingredients of Pth.  So, either welcome to
- * the club of hackers, or do yourself a favor and skip this ;)
- *
- * The ingenious fact is that this variant runs really on _all_ POSIX
- * compliant systems without special platform kludges.  But be _VERY_
- * carefully when you change something in the following code. The slightest
- * change or reordering can lead to horribly broken code.  Really every
- * function call in the following case is intended to be how it is, doubt
- * me...
- *
- * For more details we strongly recommend you to read the companion
- * paper ``Portable Multithreading -- The Signal Stack Trick for
- * User-Space Thread Creation'' from Ralf S. Engelschall. A copy of the
- * draft of this paper you can find in the file rse-pmt.ps inside the
- * GNU Pth distribution.
- */
-
-static int make_context(struct ctx *ctx, void (*f)(void), char *sp, size_t stack_size)
-{
-    struct sigaction sa;
-    struct sigaction osa;
-    stack_t ss;
-    stack_t oss;
-    sigset_t osigs;
-    sigset_t sigs;
-
-    disable_irq();
-    /*
-     * Preserve the trampoline_sig signal state, block trampoline_sig,
-     * and establish our signal handler. The signal will
-     * later transfer control onto the signal stack.
-     */
-    sigemptyset(&sigs);
-    sigaddset(&sigs, trampoline_sig);
-    sigprocmask(SIG_BLOCK, &sigs, &osigs);
-    sa.sa_handler = trampoline;
-    sigemptyset(&sa.sa_mask);
-    sa.sa_flags = SA_ONSTACK;
-    if (sigaction(trampoline_sig, &sa, &osa) != 0)
-    {
-        DEBUGF("%s(): %s\n", __func__, strerror(errno));
-        return false;
-    }
-    /*
-     * Set the new stack.
-     *
-     * For sigaltstack we're lucky [from sigaltstack(2) on
-     * FreeBSD 3.1]: ``Signal stacks are automatically adjusted
-     * for the direction of stack growth and alignment
-     * requirements''
-     *
-     * For sigstack we have to decide ourself [from sigstack(2)
-     * on Solaris 2.6]: ``The direction of stack growth is not
-     * indicated in the historical definition of struct sigstack.
-     * The only way to portably establish a stack pointer is for
-     * the application to determine stack growth direction.''
-     */
-    ss.ss_sp    = sp;
-    ss.ss_size  = stack_size;
-    ss.ss_flags = 0;
-    if (sigaltstack(&ss, &oss) < 0)
-    {
-        DEBUGF("%s(): %s\n", __func__, strerror(errno));
-        return false;
-    }
-
-    /*
-     * Now transfer control onto the signal stack and set it up.
-     * It will return immediately via "return" after the setjmp()
-     * was performed. Be careful here with race conditions.  The
-     * signal can be delivered the first time sigsuspend() is
-     * called.
-     */
-    sig_handler_called = false;
-    main_thread = pthread_self();
-    sigfillset(&sigs);
-    sigdelset(&sigs, trampoline_sig);
-    pthread_kill(main_thread, trampoline_sig);
-    while(!sig_handler_called)
-        sigsuspend(&sigs);
-
-    /*
-     * Inform the system that we are back off the signal stack by
-     * removing the alternative signal stack. Be careful here: It
-     * first has to be disabled, before it can be removed.
-     */
-    sigaltstack(NULL, &ss);
-    ss.ss_flags = SS_DISABLE;
-    if (sigaltstack(&ss, NULL) < 0)
-    {
-        DEBUGF("%s(): %s\n", __func__, strerror(errno));
-        return false;
-    }
-    sigaltstack(NULL, &ss);
-    if (!(ss.ss_flags & SS_DISABLE))
-    {
-        DEBUGF("%s(): %s\n", __func__, strerror(errno));
-        return false;
-    }
-    if (!(oss.ss_flags & SS_DISABLE))
-        sigaltstack(&oss, NULL);
-
-    /*
-     * Restore the old trampoline_sig signal handler and mask
-     */
-    sigaction(trampoline_sig, &osa, NULL);
-    sigprocmask(SIG_SETMASK, &osigs, NULL);
-
-    /*
-     * Tell the trampoline and bootstrap function where to dump
-     * the new machine context, and what to do afterwards...
-     */
-    thread_func = f;
-    thread_context  = ctx;
-
-    /*
-     * Now enter the trampoline again, but this time not as a signal
-     * handler. Instead we jump into it directly. The functionally
-     * redundant ping-pong pointer arithmentic is neccessary to avoid
-     * type-conversion warnings related to the `volatile' qualifier and
-     * the fact that `jmp_buf' usually is an array type.
-     */
-    if (setjmp(*((jmp_buf *)&bootstrap_buf)) == 0)
-        longjmp(*((jmp_buf *)&tramp_buf), 1);
-
-    /*
-     * Ok, we returned again, so now we're finished
-     */
-    enable_irq();
-    return true;
-}
-
-static void trampoline(int sig)
-{
-    (void)sig;
-    /* sanity check, no other thread should be here */
-    if (pthread_self() != main_thread)
-        return;
-
-    if (setjmp(*((jmp_buf *)&tramp_buf)) == 0)
-    {
-        sig_handler_called = true;
-        return;
-    }
-    /* longjump'd back in */
-    bootstrap_context();
-}
-
-void bootstrap_context(void)
-{
-    /* copy to local storage so we can spawn further threads
-     * in the meantime */
-    void (*thread_entry)(void) = thread_func;
-    struct ctx *t = thread_context;
-    
-    /*
-     * Save current machine state (on new stack) and
-     * go back to caller until we're scheduled for real...
-     */
-    if (setjmp(t->thread_buf) == 0)
-        longjmp(*((jmp_buf *)&bootstrap_buf), 1);
-
-    /*
-     * The new thread is now running: GREAT!
-     * Now we just invoke its init function....
-     */
-    thread_entry();
-    DEBUGF("thread left\n");
-    thread_exit();
-}
-
-static inline void set_context(struct ctx *c)
-{
-    longjmp(c->thread_buf, 1);
-}
-
-static inline void swap_context(struct ctx *old, struct ctx *new)
-{
-    if (setjmp(old->thread_buf) == 0)
-        longjmp(new->thread_buf, 1);
-}
-
-static inline void get_context(struct ctx *c)
-{
-    setjmp(c->thread_buf);
-}
-
-
-static void setup_thread(struct regs *context);
-
-#define INIT_MAIN_THREAD
-static void init_main_thread(void *addr)
-{
-    /* get a context for the main thread so that we can jump to it from
-     * other threads */
-    struct regs *context = (struct regs*)addr;
-    context->uc = &thread_bufs[curr_uc++];
-    get_context(context->uc);
-}
-
-#define THREAD_STARTUP_INIT(core, thread, function) \
-    ({ (thread)->context.stack_size = (thread)->stack_size, \
-       (thread)->context.stack = (uintptr_t)(thread)->stack; \
-       (thread)->context.start = function; })
-
-
-
-/*
- * Prepare context to make the thread runnable by calling swapcontext on it
- */
-static void setup_thread(struct regs *context)
-{
-    void (*fn)(void) = context->start;
-    context->uc = &thread_bufs[curr_uc++];
-    while (!make_context(context->uc, fn, (char*)context->stack, context->stack_size))
-        DEBUGF("Thread creation failed. Retrying");
-}
-
-
-/*
- * Save the ucontext_t pointer for later use in swapcontext()
- *
- * Cannot do getcontext() here, because jumping back to the context
- * resumes after the getcontext call (i.e. store_context), but we need
- * to resume from load_context()
- */
-static inline void store_context(void* addr)
-{
-    struct regs *r = (struct regs*)addr;
-    target_context = r->uc;
-}
-
-/*
- * Perform context switch
- */
-static inline void load_context(const void* addr)
-{
-    struct regs *r = (struct regs*)addr;
-    if (UNLIKELY(r->start))
-    {
-        setup_thread(r);
-        r->start = NULL;
-    }
-    swap_context(target_context, r->uc);
-}
-
-/*
- * play nice with the host and sleep while waiting for the tick */
-extern void wait_for_interrupt(void);
-static inline void core_sleep(void)
-{
-    enable_irq();
-    wait_for_interrupt();
-}
-
diff --git a/firmware/target/hosted/thread-win32.c b/firmware/target/hosted/thread-win32.c
deleted file mode 100644
index a601984..0000000
--- a/firmware/target/hosted/thread-win32.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2010 by Thomas Martitz
- *
- * Generic ARM threading support
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-
-
-#include <windows.h>
-#include "system.h"
-
-#define INIT_MAIN_THREAD
-
-#define THREAD_STARTUP_INIT(core, thread, function) \
-    ({ (thread)->context.stack_size = (thread)->stack_size, \
-       (thread)->context.stack = (uintptr_t)(thread)->stack; \
-       (thread)->context.start = function; })
-
-static void init_main_thread(void *addr)
-{
-    struct regs *context = (struct regs*)addr;
-    /* we must convert the current main thread to a fiber to be able to
-     * schedule other fibers */
-    context->uc = ConvertThreadToFiber(NULL);
-    context->stack_size = 0;
-}
-
-static inline void store_context(void* addr)
-{
-    (void)addr;
-    /* nothing to do here, Fibers continue after the SwitchToFiber call */
-}
-
-static void start_thread(void)
-{
-    void (*func)(void) = GetFiberData();
-    func();
-    /* go out if thread function returns */
-    thread_exit();
-}
-
-/*
- * Load context and run it
- *
- * Resume execution from the last load_context call for the thread
- */
-
-static inline void load_context(const void* addr)
-{
-    struct regs *context = (struct regs*)addr;
-    if (UNLIKELY(context->start))
-    {   /* need setup before switching to it */
-        context->uc = CreateFiber(context->stack_size,
-                        (LPFIBER_START_ROUTINE)start_thread, context->start);
-        /* can't assign stack pointer, only stack size */
-        context->stack_size = 0;
-        context->start = NULL;
-    }
-    SwitchToFiber(context->uc);
-}
-
-/*
- * play nice with the host and sleep while waiting for the tick */
-static inline void core_sleep(void)
-{
-    enable_irq();
-    wait_for_interrupt();
-}
-
diff --git a/firmware/thread.c b/firmware/thread.c
index ea73150..b71bc17 100644
--- a/firmware/thread.c
+++ b/firmware/thread.c
@@ -174,13 +174,10 @@ void switch_thread(void)
         __attribute__((noinline));

 /****************************************************************************
- * Processor/OS-specific section - include necessary core support
+ * Processor-specific section - include necessary core support
  */
-
-#if defined(HAVE_WIN32_FIBER_THREADS)
-#include "thread-win32.c"
-#elif defined(HAVE_SIGALTSTACK_THREADS)
-#include "thread-unix.c"
+#if defined(ANDROID)
+#include "thread-android-arm.c"
 #elif defined(CPU_ARM)
 #include "thread-arm.c"
 #if defined (CPU_PP)
@@ -967,7 +964,7 @@ void check_tmo_threads(void)
              * life again. */
             if (state == STATE_BLOCKED_W_TMO)
             {
-#ifdef HAVE_CORELOCK_OBJECT
+#if NUM_CORES > 1
                 /* Lock the waiting thread's kernel object */
                 struct corelock *ocl = curr->obj_cl;

@@ -1782,7 +1779,7 @@ void thread_exit(void)
  */
 void remove_thread(unsigned int thread_id)
 {
-#ifdef HAVE_CORELOCK_OBJECT
+#if NUM_CORES > 1
     /* core is not constant here because of core switching */
     unsigned int core = CURRENT_CORE;
     unsigned int old_core = NUM_CORES;
@@ -2311,9 +2308,6 @@ void init_threads(void)
         thread_exit();
 #endif /* NUM_CORES */
     }
-#ifdef INIT_MAIN_THREAD
-    init_main_thread(&thread->context);
-#endif
 }

 /* Shared stack scan helper for thread_stack_usage and idle_stack_usage */
@@ -2385,7 +2379,7 @@ void thread_get_name(char *buffer, int size,
         const char *fmt = "%s";
         if (name == NULL IF_COP(|| name == THREAD_DESTRUCT) || *name == '\0')
         {
-            name = (const char *)(uintptr_t)thread->id;
+            name = (const char *)(unsigned int)thread->id;
             fmt = "%04lX";
         }
         snprintf(buffer, size, fmt, name);
diff --git a/tools/configure b/tools/configure
index 6a060de..bcb7d0a 100755
--- a/tools/configure
+++ b/tools/configure
@@ -25,7 +25,6 @@ bindir=
 libdir=
 sharedir=

-thread_support="ASSEMBLER_THREADS"
 app_modelname=
 app_lcd_width=
 app_lcd_height=
@@ -164,41 +163,6 @@ findsdl(){
   done
 }

-# check for availability of sigaltstack to support our thread engine
-check_sigaltstack() {
-   cat >$tmpdir/check_threads.c <<EOF
-#include <signal.h>
-int main(int argc, char **argv)
-{
-#ifndef NULL
-  #define NULL (void*)0
-#endif
-  sigaltstack(NULL, NULL);
-  return 0;
-}
-EOF
-   $CC -o $tmpdir/check_threads $tmpdir/check_threads.c 1> /dev/null
-   result=$?
-   rm -rf $tmpdir/check_threads*
-   echo $result
-}
-
-# check for availability of Fiber on Win32 to support our thread engine
-check_fiber() {
-   cat >$tmpdir/check_threads.c <<EOF
-#include <windows.h>
-int main(int argc, char **argv)
-{
-  ConvertThreadToFiber(NULL);
-  return 0;
-}
-EOF
-   $CC -o $tmpdir/check_threads $tmpdir/check_threads.c 2>/dev/null
-   result=$?
-   rm -rf $tmpdir/check_threads*
-   echo $result
-}
-
 simcc () {

  # default tool setup for native building
@@ -211,8 +175,6 @@ simcc () {
  GCCOPTS="$GCCOPTS -fno-builtin -g"
  GCCOPTIMIZE=''
  LDOPTS='-lm' # button-sdl.c uses sqrt()
- sigaltstack=""
- fibers=""

  # default output binary name, don't override app_get_platform()
  if [ "$app_type" != "sdl-app" ]; then
@@ -231,7 +193,6 @@ simcc () {
    CYGWIN*)
    echo "Cygwin host detected"

-   fibers=`check_fiber`
    LDOPTS="$LDOPTS -mconsole"
    output="$output.exe"
    winbuild="yes"
@@ -240,33 +201,29 @@ simcc () {
    MINGW*)
    echo "MinGW host detected"

-   fibers=`check_fiber`
    LDOPTS="$LDOPTS -mconsole"
    output="$output.exe"
    winbuild="yes"
    ;;

    Linux)
-   sigaltstack=`check_sigaltstack`
    echo "Linux host detected"
    LDOPTS="$LDOPTS -ldl"
    ;;

    FreeBSD)
-   sigaltstack=`check_sigaltstack`
    echo "FreeBSD host detected"
    LDOPTS="$LDOPTS -ldl"
    ;;

    Darwin)
-   sigaltstack=`check_sigaltstack`
    echo "Darwin host detected"
    LDOPTS="$LDOPTS -ldl"
+
    SHARED_FLAG="-dynamiclib -Wl\,-single_module"
    ;;

    SunOS)
-   sigaltstack=`check_sigaltstack`
    echo "*Solaris host detected"

    GCCOPTS="$GCCOPTS -fPIC"
@@ -362,34 +319,11 @@ EOF
    # add cross-compiler option(s)
    prefixtools i586-mingw32msvc-
    LDOPTS="$LDOPTS -mconsole"
-   fibers=`check_fiber`
    output="rockboxui.exe"
    endian="little" # windows is little endian
    echo "Enabling MMX support"
    GCCOPTS="$GCCOPTS -mmmx"
  fi
-
- thread_support=
- if [ -z "$ARG_THREAD_SUPPORT" ] || [ "$ARG_THREAD_SUPPORT" = "0" ]; then
-   if [ "$sigaltstack" = "0" ]; then
-     thread_support="HAVE_SIGALTSTACK_THREADS"
-     LDOPTS="$LDOPTS -lpthread" # pthread needed
-     echo "Selected sigaltstack threads"
-   elif [ "$fibers" = "0" ]; then
-     thread_support="HAVE_WIN32_FIBER_THREADS"
-     echo "Selected Win32 Fiber threads"
-   fi
- fi
-
- if [ -n `echo $app_type | grep "sdl"` ] && [ -z "$thread_support" ] \
-    && [ "$ARG_THREAD_SUPPORT" != "0" ]; then
-   thread_support="HAVE_SDL_THREADS"
-   if [ "$ARG_THREAD_SUPPORT" = "1" ]; then
-     echo "Selected SDL threads"
-   else
-     echo "WARNING: Falling back to SDL threads"
-   fi
- fi
 }

 #
@@ -522,7 +456,6 @@ maemocc () {
  GLOBAL_LDOPTS="$GLOBAL_LDOPTS -Wl,-z,defs"
  SHARED_FLAG="-shared"
  endian="little"
- thread_support="HAVE_SIGALTSTACK_THREADS"

  is_n900=0
  # Determine maemo version
@@ -1061,11 +994,6 @@ help() {
     --thumb           Build with -mthumb (for ARM builds)
     --no-thumb        The opposite of --thumb (don't use thumb even for targets
                       where this is the default
-    --sdl-threads     Force use of SDL threads. They have inferior performance,
-                      but are better debuggable with GDB
-    --no-sdl-threads  Disallow use of SDL threads. This prevents the default
-                      behavior of falling back to them if no native thread
-                      support was found.
     --prefix          Target installation directory
     --help            Shows this message (must not be used with other options)

@@ -1087,7 +1015,6 @@ ARG_VOICE=
 ARG_ARM_EABI=
 ARG_ARM_THUMB=
 ARG_PREFIX="$PREFIX"
-ARG_THREAD_SUPPORT=
 err=
 for arg in "$@"; do
 	case "$arg" in
@@ -1108,9 +1035,6 @@ for arg in "$@"; do
 		--no-eabi)    ARG_ARM_EABI=0;;
 		--thumb)      ARG_ARM_THUMB=1;;
 		--no-thumb)   ARG_ARM_THUMB=0;;
-        --sdl-threads)ARG_THREAD_SUPPORT=1;;
-        --no-sdl-threads)
-                      ARG_THREAD_SUPPORT=0;;
         --prefix=*)   ARG_PREFIX=`echo "$arg" | cut -d = -f 2`;;
 		--help)       help;;
 		*)            err=1; echo "[ERROR] Option '$arg' unsupported";;
@@ -3402,7 +3326,6 @@ sed > autoconf.h \
  -e "s<^#undef DO_BOOTCHART<$use_bootchart<g" \
  -e "s<@config_rtc@<$config_rtc<g" \
  -e "s<@have_rtc_alarm@<$have_rtc_alarm<g" \
- -e "s<@thread_support@<$thread_support<g" \
  -e "s<@RBDIR@<${rbdir}<g" \
  -e "s<@sharepath@<${sharedir}<g" \
  -e "s<@binpath@<${bindir}<g" \
@@ -3439,9 +3362,6 @@ sed > autoconf.h \
 @config_rtc@
 @have_rtc_alarm@

-/* the threading backend we use */
-#define @thread_support@
-
 /* lcd dimensions for application builds from configure */
 @lcd_width@
 @lcd_height@
diff --git a/uisimulator/common/io.c b/uisimulator/common/io.c
index 0d680e0..f77180d 100644
--- a/uisimulator/common/io.c
+++ b/uisimulator/common/io.c
@@ -46,12 +46,9 @@
 #endif

 #include <fcntl.h>
-#ifdef HAVE_SDL_THREADS
+#include <SDL.h>
+#include <SDL_thread.h>
 #include "thread-sdl.h"
-#else
-#define sim_thread_unlock() NULL
-#define sim_thread_lock(a)
-#endif
 #include "thread.h"
 #include "kernel.h"
 #include "debug.h"