os/kernelhwsrv/kerneltest/e32test/thread/smpsafe.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // e32test\thread\smpsafe.cpp
    15 // 
    16 //
    17 
    18 #include <e32std.h>
    19 #include <e32std_private.h>
    20 #include <e32atomics.h>
    21 
    22 IMPORT_C void DoNothingA();
    23 IMPORT_C void DoNothingB();
    24 IMPORT_C void DoNothingC();
    25 IMPORT_C void DoNothingD();
    26 IMPORT_C void DoNothingE();
    27 
    28 #ifdef MAKE_DLL
    29 
    30 #ifdef PROVIDE_A
    31 EXPORT_C void DoNothingA() {}
    32 #endif
    33 
    34 #ifdef PROVIDE_B
    35 EXPORT_C void DoNothingB() { DoNothingA(); }
    36 #endif
    37 
    38 #ifdef PROVIDE_C
    39 EXPORT_C void DoNothingC() { DoNothingD(); DoNothingE(); }
    40 #endif
    41 
    42 #ifdef PROVIDE_D
    43 EXPORT_C void DoNothingD() { DoNothingC(); }
    44 #endif
    45 
    46 #ifdef PROVIDE_E
    47 EXPORT_C void DoNothingE() { DoNothingC(); }
    48 #endif
    49 
    50 #else // !MAKE_DLL
    51 
    52 volatile TInt Affinity;
    53 RSemaphore Start;
    54 RSemaphore Stop;
    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.
    63 TInt AffinitySlave(TAny*)
    64 	{
    65 	for (TInt i = KLoopTries; i>0; --i)
    66 		{
    67 		Start.Wait();
    68 		Affinity = 0;
    69 		Stop.Signal();
    70 		}
    71 	return KErrNone;
    72 	}
    73 
    74 TInt CheckAffinity()
    75 	{
    76 	RThread t;
    77 	TInt r = t.Create(_L("AffinitySlave"), AffinitySlave, KDefaultStackSize, NULL, NULL);
    78 	if (r != KErrNone)
    79 		return r;
    80 
    81 	Start.CreateLocal(0);
    82 	Stop.CreateLocal(0);
    83 
    84 	TRequestStatus s;
    85 	t.Logon(s);
    86 	t.SetPriority(EPriorityLess);
    87 	t.Resume();
    88 
    89 	TInt a = 1;
    90 	for (TInt i = KLoopTries; i>0; --i)
    91 		{
    92 		Affinity = 1; // assume we are locked to a single cpu
    93 		Start.Signal(); // tell the other thread to run
    94 		TUint32 target = User::NTickCount() + 10;
    95 		while (User::NTickCount() < target)
    96 			{
    97 			// spin, waiting to see if the other thread actually *does* run
    98 			}
    99 		a = Affinity;
   100 		if (a == 0)
   101 			break;
   102 		Stop.Wait(); // We didn't see it this time, but try again in case of scheduling fluke
   103 		}
   104 
   105 	t.Kill(0);
   106 	User::WaitForRequest(s);
   107 	t.Close();
   108 
   109 	return a;
   110 	}
   111 
   112 #ifndef OMIT_MAIN
   113 GLDEF_C TInt E32Main()
   114 	{
   115 #ifdef USE_A
   116 	DoNothingA();
   117 #endif
   118 #ifdef USE_B
   119 	DoNothingB();
   120 #endif
   121 	return CheckAffinity();
   122 	}
   123 #endif // OMIT_MAIN
   124 
   125 #endif