47 EXPORT_C void DoNothingE() { DoNothingC(); } |
47 EXPORT_C void DoNothingE() { DoNothingC(); } |
48 #endif |
48 #endif |
49 |
49 |
50 #else // !MAKE_DLL |
50 #else // !MAKE_DLL |
51 |
51 |
52 TInt Affinity; |
52 volatile TInt Affinity; |
|
53 RSemaphore Start; |
|
54 RSemaphore Stop; |
53 |
55 |
|
56 const TInt KLoopTries = 100; |
|
57 |
|
58 // This gets run in a low priority thread. Each time around the loop it waits to be told to go, |
|
59 // then sets Affinity to 0, then tells the other thread it's done. If we're actually locked to |
|
60 // the same processor as the main thread, however, then we won't get to run until the other thread |
|
61 // waits for the Stop semaphore, and thus Affinity will not get set to 0 until the other thread |
|
62 // checked it already. |
54 TInt AffinitySlave(TAny*) |
63 TInt AffinitySlave(TAny*) |
55 { |
64 { |
56 for (;;) |
65 for (TInt i = KLoopTries; i>0; --i) |
57 { |
66 { |
58 __e32_atomic_store_rel32(&Affinity, 0); // we can't be locked if this runs |
67 Start.Wait(); |
59 User::AfterHighRes(1); |
68 Affinity = 0; |
|
69 Stop.Signal(); |
60 } |
70 } |
|
71 return KErrNone; |
61 } |
72 } |
62 |
73 |
63 TInt CheckAffinity() |
74 TInt CheckAffinity() |
64 { |
75 { |
65 __e32_atomic_store_rel32(&Affinity, 1); // assume we are locked to a single cpu |
|
66 |
|
67 RThread t; |
76 RThread t; |
68 TInt r = t.Create(_L("AffinitySlave"), AffinitySlave, KDefaultStackSize, NULL, NULL); |
77 TInt r = t.Create(_L("AffinitySlave"), AffinitySlave, KDefaultStackSize, NULL, NULL); |
69 if (r != KErrNone) |
78 if (r != KErrNone) |
70 return r; |
79 return r; |
|
80 |
|
81 Start.CreateLocal(0); |
|
82 Stop.CreateLocal(0); |
71 |
83 |
72 TRequestStatus s; |
84 TRequestStatus s; |
73 t.Logon(s); |
85 t.Logon(s); |
74 t.SetPriority(EPriorityLess); |
86 t.SetPriority(EPriorityLess); |
75 t.Resume(); |
87 t.Resume(); |
76 |
88 |
77 TUint32 target = User::NTickCount() + 10; |
89 for (TInt i = KLoopTries; i>0; --i) |
78 while (User::NTickCount() < target) {} |
90 { |
79 |
91 Affinity = 1; // assume we are locked to a single cpu |
80 r = __e32_atomic_load_acq32(&Affinity); |
92 Start.Signal(); // tell the other thread to run |
|
93 TUint32 target = User::NTickCount() + 10; |
|
94 while (User::NTickCount() < target) |
|
95 { |
|
96 // spin, waiting to see if the other thread actually *does* run |
|
97 } |
|
98 if (Affinity == 0) |
|
99 break; |
|
100 Stop.Wait(); // We didn't see it this time, but try again in case of scheduling fluke |
|
101 } |
81 |
102 |
82 t.Kill(0); |
103 t.Kill(0); |
83 User::WaitForRequest(s); |
104 User::WaitForRequest(s); |
84 t.Close(); |
105 t.Close(); |
85 |
106 |
86 return r; |
107 return Affinity; |
87 } |
108 } |
88 |
109 |
89 #ifndef OMIT_MAIN |
110 #ifndef OMIT_MAIN |
90 GLDEF_C TInt E32Main() |
111 GLDEF_C TInt E32Main() |
91 { |
112 { |