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