Пример #1
0
void testLock(void)
{
        gslLockMode_t mode1 = PERPROC(curProc)->testMode1;
        bool mode1DontWait  = PERPROC(curProc)->testMode1DontWait;
        gslLockMode_t mode2 = PERPROC(curProc)->testMode2;
        bool mode2DontWait  = PERPROC(curProc)->testMode2DontWait;
        bool got1 = false, got2 = false;

        got1 = gslAcquire(&theLock, mode1, mode1DontWait, NULL);
        if (got1)
                holderCounts = lcAdd(holderCounts, lcActive(mode1));
        swtch();
        if (mode2 != -1) {
                got2 = gslAcquire(&theLock, mode2, mode2DontWait, NULL);
                if (got2)
                        holderCounts = lcAdd(holderCounts, lcActive(mode2));
                swtch();
        }

        // Check for conflicting held locks
        lockCounts_t otherCounts = lcSubtract(holderCounts, PERPROC(curProc)->perLock.holding);
        for (int i = 0; i < LC_MAX_MODES; ++i) {
                if (lcGetActive(otherCounts, i)) {
                        if ((got1 && CONFLICTS(i, mode1)) || (got2 && CONFLICTS(i, mode2))) {
                                fail("Conflicting lock held");
                        } else if ((got1 && i == mode1) || (got2 && i == mode2)) {
                                observedSharing[i] = true;
                        }
                }
        }

        // I release mode1 first so that my tests for observed sharing
        // remain simple.  Otherwise, if mode1 overshadows mode2, then
        // it could prevent sharing of mode2, even if mode2 would
        // otherwise be sharable.  (This isn't entirely reliable, but
        // takes care of most cases)
        if (got1) {
                holderCounts = lcSubtract(holderCounts, lcActive(mode1));
                // XXX Check lastlocalhold and lasthold
                gslRelease(&theLock, mode1, NULL, NULL);
        }
        if (got2) {
                holderCounts = lcSubtract(holderCounts, lcActive(mode2));
                gslRelease(&theLock, mode2, NULL, NULL);
        }
}
Пример #2
0
/**
 * @fn int CacheMissComputation::computation(FrameWork *ws, AST *ast);
 * Compute the number of Miss for each AST node by using annotations coming from other modules. 
 * Furthermore put annotations (ETS::MISSES) of each AST node.
 * @param ws	Container framework.
 * @param ast	AST to process.
 * @return Miss of the current AST.
 */
int CacheMissComputation::computation(WorkSpace *ws, AST *ast){
	int misses;
	switch (ast->kind()){
		case AST_Call:{	
			ASTInfo *ast_info = ws->getASTInfo();
			Option< FunAST *> fun_res = ast_info->get(ast->toCall()->function()->name());
			if (fun_res){
				AST *fun_ast = (*fun_res)->ast();
				misses = computation(ws, fun_ast);
				MISSES(ast->toCall()) = misses;
				CHC_OUT(cout << "|| " << ast->toCall()->function()->name() << " a pour nb de miss : " << ast->toCall()->use<int>(ETS::ID_MISSES)<< '\n');	
				return MISSES(ast->toCall());
			}
			break;
		}
		case AST_Block: 
			CHC_OUT(cout << "|| " << ast->toBlock()->first()->get<String>(File::ID_Label,"unknown ") << " a pour nb de miss : " << ast->toBlock()->use<int>(ETS::ID_MISSES)<< '\n');
			return MISSES(ast->toBlock()) + CONFLICTS(ast->toBlock());
			break;
		case AST_Seq: {	
			misses = 	computation(ws, ast->toSeq()->child1())
						+ computation(ws, ast->toSeq()->child2());
			MISSES(ast->toSeq()) = misses;
			CHC_OUT(cout << "|| " << ast->toSeq()->first()->get<String>(File::ID_Label,"unknown ") << " a pour nb de miss : " << ast->toSeq()->use<int>(ETS::ID_MISSES)<< '\n');
			return MISSES(ast->toSeq());
			break;
		}
		case AST_If: {
		 	misses = computation(ws, ast->toIf()->elsePart());
			int misses1 = computation(ws, ast->toIf()->thenPart());
			if(misses < misses1)
				MISSES(ast->toIf()) = misses1 + computation(ws, ast->toIf()->condition());
			else
				MISSES(ast->toIf()) = misses + computation(ws, ast->toIf()->condition());
			CHC_OUT(cout << "|| " << ast->toIf()->condition()->first()->get<String>(File::ID_Label,"unknown ") << " a pour nb de miss : " << ast->toIf()->use<int>(ETS::ID_MISSES)<< '\n');
			return MISSES(ast->toIf());
			break;
		}
		case AST_While:	{
			int N = LOOP_COUNT(ast->toWhile());
			
			misses = 	computation(ws, ast->toWhile()->condition())
						+ N
						*( 	computation(ws, ast->toWhile()->condition())
							+ computation(ws, ast->toWhile()->body()));
							
			int misses_coming_from_first_misses =
				FIRST_MISSES(ast->toWhile()->condition())
				+ FIRST_MISSES(ast->toWhile()->body());	
			
			MISSES(ast->toWhile()) = misses + misses_coming_from_first_misses;
			CHC_OUT(cout << "|| " << ast->toWhile()->condition()->first()->get<String>(File::ID_Label,"unknown ") << " a pour nb de miss : " << ast->toWhile()->use<int>(ETS::ID_MISSES)<< '\n');
			return MISSES(ast->toWhile());
			break;
		}
		case AST_For:	{	
			int N = LOOP_COUNT(ast->toFor());
			
			misses = 	computation(ws, ast->toFor()->condition())
						+ computation(ws, ast->toFor()->initialization())
						+ N
						*( 	computation(ws, ast->toFor()->condition())
							+ computation(ws, ast->toFor()->body())
							+ computation(ws, ast->toFor()->incrementation()));
			
			int misses_coming_from_first_misses =
				FIRST_MISSES(ast->toFor()->condition())
				+ FIRST_MISSES(ast->toFor()->body()) 
				+ FIRST_MISSES(ast->toFor()->incrementation());
					
			MISSES(ast->toFor()) = misses + misses_coming_from_first_misses;
			CHC_OUT(cout << "|| " << ast->toFor()->condition()->first()->get<String>(File::ID_Label,"unknown ") << " a pour nb de miss : " << ast->toFor()->use<int>(ETS::ID_MISSES)<< '\n');
			return MISSES(ast->toFor());
			break;
		}
		case AST_DoWhile:	{
			int N = LOOP_COUNT(ast->toDoWhile());
			
			misses = 	computation(ws, ast->toDoWhile()->body())
						+ N
						*( 	computation(ws, ast->toDoWhile()->condition())
							+ computation(ws, ast->toDoWhile()->body()));
							
			int misses_coming_from_first_misses =
				FIRST_MISSES(ast->toDoWhile()->body())
				+ FIRST_MISSES(ast->toDoWhile()->condition());
			
			MISSES(ast->toDoWhile()) = misses + misses_coming_from_first_misses;
			CHC_OUT(cout << "|| " << ast->toDoWhile()->condition()->first()->get<String>(File::ID_Label,"unknown ") << " a pour nb de miss : " << ast->toDoWhile()->use<int>(ETS::ID_MISSES)<< '\n');
			return MISSES(ast->toDoWhile());
			break;
		}
		default :
			return 0;
	}
	return 0;
}
Пример #3
0
void doRun(void)
{
        // Print mode combination
        for (int i = 0; i < nProcs; ++i) {
                if (i != 0)
                        printf(" ");
                printf("%d%s/%d%s",
                       PERPROC(&procs[i])->testMode1,
                       PERPROC(&procs[i])->testMode1DontWait ? "(NB)" : "",
                       PERPROC(&procs[i])->testMode2,
                       PERPROC(&procs[i])->testMode2DontWait ? "(NB)" : "");
        }
        printf("\n");

        // Do I *expect* deadlock from this combination?  Ideally I
        // would ignore the particular bad interleavings, but this
        // will do.
        if (nProcs == 2) {
                gslLockMode_t
                        mode01 = PERPROC(&procs[0])->testMode1,
                        mode02 = PERPROC(&procs[0])->testMode2,
                        mode11 = PERPROC(&procs[1])->testMode1,
                        mode12 = PERPROC(&procs[1])->testMode2;
                if (mode02 != -1 && mode12 != -1) {
                        if (CONFLICTS(mode01, mode12) && CONFLICTS(mode02, mode11)) {
                                printf("SKIPPING\n");
                                return;
                        }
                }
        }

        // Reset expected sharing tracking
        memset(observedSharing, 0, sizeof observedSharing);

        // Reset counters
        memset(&counters, 0, sizeof counters);

        // Run every interleaving
        procRun();

        // Count number of threads for each lock mode
        int modeCounts[LC_MAX_MODES];
        memset(modeCounts, 0, sizeof modeCounts);
        for (int i = 0; i < nProcs; ++i) {
                modeCounts[PERPROC(&procs[i])->testMode1]++;
                if (PERPROC(&procs[i])->testMode2 != -1)
                        modeCounts[PERPROC(&procs[i])->testMode2]++;
        }

        // Check for expected sharing
        for (int i = 0; i < LC_MAX_MODES; ++i) {
                if (modeCounts[i] > 1 && !CONFLICTS(i, i)) {
                        // Expected sharing to show up in some
                        // interleaving
                        if (!observedSharing[i])
                                printf("WARNING: No sharing observed for mode %d\n", i);
                }
        }

        // Print counters
        printf("acquireCalls: %d\t releaseCalls: %d\t "
               "wakeCalls: %d\t spuriousWakes: %d\n",
               counters.acquireCalls, counters.releaseCalls,
               counters.wakeCalls, counters.spuriousWakes);
}