Пример #1
0
void psi_memstall_tick(struct task_struct *task, int cpu)
{
	struct psi_group *group;
	void *iter = NULL;

	while ((group = iterate_groups(task, &iter))) {
		struct psi_group_cpu *groupc;

		groupc = per_cpu_ptr(group->pcpu, cpu);
		write_seqcount_begin(&groupc->seq);
		record_times(groupc, cpu, true);
		write_seqcount_end(&groupc->seq);
	}
}
Пример #2
0
    inline typename property_traits<Components>::value_type
    connected_components(Graph& G, DFSVisitor v, Components c, DiscoverTime d,
                         FinishTime f, Color color, directed_tag)
    {
      typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
      typename property_traits<Color>::value_type cc = get(color, Vertex());
      int time = 0;
      depth_first_search(G, record_times(d, f, time, v), color);

      Graph G_T(num_vertices(G));
      transpose_graph(G, G_T);

      typedef typename property_traits<Components>::value_type count_type;

      count_type c_count(0);
      components_recorder<Components, dfs_visitor<> > 
        vis(c, c_count, dfs_visitor<>());

      // initialize G_T
      typename graph_traits<Graph>::vertex_iterator ui, ui_end;
      for (tie(ui, ui_end) = vertices(G_T); ui != ui_end; ++ui)
        put(color, *ui, white(cc));

      typedef typename property_traits<FinishTime>::value_type D;
      typedef indirect_cmp< FinishTime, std::less<D> > Compare;

      Compare fl(f);
      priority_queue<Vertex, std::vector<Vertex>, Compare > Q(fl);

      typename graph_traits<Graph>::vertex_iterator i, j, iend, jend;
      tie(i, iend) = vertices(G_T);
      tie(j, jend) = vertices(G);
      for ( ; i != iend; ++i, ++j) {
        put(f, *i, get(f, *j));
         Q.push(*i);
      }

      while ( !Q.empty() ) {
        Vertex u = Q.top();
        Q.pop();
        if  (get(color, u) == white(cc)) {
          depth_first_visit(G_T, u, vis, color);
          ++c_count; 
        }
      }
      return c_count;
    }
Пример #3
0
static void psi_group_change(struct psi_group *group, int cpu,
			     unsigned int clear, unsigned int set)
{
	struct psi_group_cpu *groupc;
	unsigned int t, m;

	groupc = per_cpu_ptr(group->pcpu, cpu);

	/*
	 * First we assess the aggregate resource states this CPU's
	 * tasks have been in since the last change, and account any
	 * SOME and FULL time these may have resulted in.
	 *
	 * Then we update the task counts according to the state
	 * change requested through the @clear and @set bits.
	 */
	write_seqcount_begin(&groupc->seq);

	record_times(groupc, cpu, false);

	for (t = 0, m = clear; m; m &= ~(1 << t), t++) {
		if (!(m & (1 << t)))
			continue;
		if (groupc->tasks[t] == 0 && !psi_bug) {
			printk_deferred(KERN_ERR "psi: task underflow! cpu=%d t=%d tasks=[%u %u %u] clear=%x set=%x\n",
					cpu, t, groupc->tasks[0],
					groupc->tasks[1], groupc->tasks[2],
					clear, set);
			psi_bug = 1;
		}
		groupc->tasks[t]--;
	}

	for (t = 0; set; set &= ~(1 << t), t++)
		if (set & (1 << t))
			groupc->tasks[t]++;

	write_seqcount_end(&groupc->seq);
}
Пример #4
0
void exec_wait()
{
    int i = -1;
    int exit_reason;  /* reason why a command completed */

    /* Wait for a command to complete, while snarfing up any output. */
    while ( 1 )
    {
        /* Check for a complete command, briefly. */
        i = try_wait( 500 );
        /* Read in the output of all running commands. */
        read_output();
        /* Close out pending debug style dialogs. */
        close_alerts();
        /* Process the completed command we found. */
        if ( i >= 0 ) { exit_reason = EXIT_OK; break; }
        /* Check if a command ran out of time. */
        i = try_kill_one();
        if ( i >= 0 ) { exit_reason = EXIT_TIMEOUT; break; }
    }

    /* We have a command... process it. */
    {
        DWORD exit_code;
        timing_info time;
        int rstat;

        /* The time data for the command. */
        record_times( cmdtab[ i ].pi.hProcess, &time );

        /* Removed the used temporary command file. */
        if ( cmdtab[ i ].command_file->size )
            unlink( cmdtab[ i ].command_file->value );

        /* Find out the process exit code. */
        GetExitCodeProcess( cmdtab[ i ].pi.hProcess, &exit_code );

        /* The dispossition of the command. */
        if ( interrupted() )
            rstat = EXEC_CMD_INTR;
        else if ( exit_code )
            rstat = EXEC_CMD_FAIL;
        else
            rstat = EXEC_CMD_OK;

        /* Call the callback, may call back to jam rule land. */
        (*cmdtab[ i ].func)( cmdtab[ i ].closure, rstat, &time,
            cmdtab[ i ].buffer_out->value, cmdtab[ i ].buffer_err->value,
            exit_reason );

        /* Clean up our child process tracking data. No need to clear the
         * temporary command file name as it gets reused.
         */
        closeWinHandle( &cmdtab[ i ].pi.hProcess );
        closeWinHandle( &cmdtab[ i ].pi.hThread );
        closeWinHandle( &cmdtab[ i ].pipe_out[ EXECCMD_PIPE_READ ] );
        closeWinHandle( &cmdtab[ i ].pipe_out[ EXECCMD_PIPE_WRITE ] );
        closeWinHandle( &cmdtab[ i ].pipe_err[ EXECCMD_PIPE_READ ] );
        closeWinHandle( &cmdtab[ i ].pipe_err[ EXECCMD_PIPE_WRITE ] );
        string_renew( cmdtab[ i ].buffer_out );
        string_renew( cmdtab[ i ].buffer_err );
    }
}
Пример #5
0
int exec_wait()
{
    int i = -1;

    /* Handle naive make1() which does not know if cmds are running. */
    if ( !cmdsrunning )
        return 0;

    /* Wait for a command to complete, while snarfing up any output. */
    do
    {
        /* Check for a complete command, briefly. */
        i = try_wait(500);
        /* Read in the output of all running commands. */
        read_output();
        /* Close out pending debug style dialogs. */
        close_alerts();
        /* Check if a command ran out of time. */
        if ( i < 0 ) i = try_kill_one();
    }
    while ( i < 0 );

    /* We have a command... process it. */
    --cmdsrunning;
    {
        timing_info time;
        int rstat;

        /* The time data for the command. */
        record_times( cmdtab[ i ].pi.hProcess, &time );

        /* Clear the temp file. */
        if ( cmdtab[ i ].tempfile_bat )
        {
            unlink( cmdtab[ i ].tempfile_bat );
            BJAM_FREE( cmdtab[ i ].tempfile_bat );
            cmdtab[ i ].tempfile_bat = NULL;
        }

        /* Find out the process exit code. */
        GetExitCodeProcess( cmdtab[ i ].pi.hProcess, &cmdtab[ i ].exit_code );

        /* The dispossition of the command. */
        if ( intr )
            rstat = EXEC_CMD_INTR;
        else if ( cmdtab[ i ].exit_code != 0 )
            rstat = EXEC_CMD_FAIL;
        else
            rstat = EXEC_CMD_OK;

        /* Output the action block. */
        out_action(
            cmdtab[ i ].action.size     > 0 ? cmdtab[ i ].action.value     : 0,
            cmdtab[ i ].target.size     > 0 ? cmdtab[ i ].target.value     : 0,
            cmdtab[ i ].command.size    > 0 ? cmdtab[ i ].command.value    : 0,
            cmdtab[ i ].buffer_out.size > 0 ? cmdtab[ i ].buffer_out.value : 0,
            cmdtab[ i ].buffer_err.size > 0 ? cmdtab[ i ].buffer_err.value : 0,
            cmdtab[ i ].exit_reason );

        /* Call the callback, may call back to jam rule land. Assume -p0 in
         * effect so only pass buffer containing merged output.
         */
        (*cmdtab[ i ].func)(
            cmdtab[ i ].closure,
            rstat,
            &time,
            cmdtab[ i ].command.value,
            cmdtab[ i ].buffer_out.value );

        /* Clean up the command data, process, etc. */
        string_free( &cmdtab[ i ].action  ); string_new( &cmdtab[ i ].action  );
        string_free( &cmdtab[ i ].target  ); string_new( &cmdtab[ i ].target  );
        string_free( &cmdtab[ i ].command ); string_new( &cmdtab[ i ].command );
        if ( cmdtab[ i ].pi.hProcess   ) { CloseHandle( cmdtab[ i ].pi.hProcess   ); cmdtab[ i ].pi.hProcess   = 0; }
        if ( cmdtab[ i ].pi.hThread    ) { CloseHandle( cmdtab[ i ].pi.hThread    ); cmdtab[ i ].pi.hThread    = 0; }
        if ( cmdtab[ i ].pipe_out[ 0 ] ) { CloseHandle( cmdtab[ i ].pipe_out[ 0 ] ); cmdtab[ i ].pipe_out[ 0 ] = 0; }
        if ( cmdtab[ i ].pipe_out[ 1 ] ) { CloseHandle( cmdtab[ i ].pipe_out[ 1 ] ); cmdtab[ i ].pipe_out[ 1 ] = 0; }
        if ( cmdtab[ i ].pipe_err[ 0 ] ) { CloseHandle( cmdtab[ i ].pipe_err[ 0 ] ); cmdtab[ i ].pipe_err[ 0 ] = 0; }
        if ( cmdtab[ i ].pipe_err[ 1 ] ) { CloseHandle( cmdtab[ i ].pipe_err[ 1 ] ); cmdtab[ i ].pipe_err[ 1 ] = 0; }
        string_free( &cmdtab[ i ].buffer_out ); string_new( &cmdtab[ i ].buffer_out );
        string_free( &cmdtab[ i ].buffer_err ); string_new( &cmdtab[ i ].buffer_err );
        cmdtab[ i ].exit_code = 0;
        cmdtab[ i ].exit_reason = EXIT_OK;
    }

    return 1;
}
Пример #6
0
int
execwait()
{
	int i;
	int status, w;
	int rstat;
    timing_info time;

	/* Handle naive make1() which doesn't know if cmds are running. */

	if( !cmdsrunning )
	    return 0;

    if ( is_win95 )
        return 0;
          
	/* Pick up process pid and status */
    
    while( ( w = wait( &status ) ) == -1 && errno == EINTR )
        ;

	if( w == -1 )
	{
	    printf( "child process(es) lost!\n" );
	    perror("wait");
	    exit( EXITBAD );
	}

	/* Find the process in the cmdtab. */

	for( i = 0; i < MAXJOBS; i++ )
	    if( w == cmdtab[ i ].pid )
		break;

	if( i == MAXJOBS )
	{
	    printf( "waif child found!\n" );
	    exit( EXITBAD );
	}

    record_times(cmdtab[i].pid, &time);
    
	/* Clear the temp file */
    if ( cmdtab[i].tempfile )
        unlink( cmdtab[ i ].tempfile );

	/* Drive the completion */

	if( !--cmdsrunning )
	    signal( SIGINT, istat );

	if( intr )
	    rstat = EXEC_CMD_INTR;
	else if( w == -1 || status != 0 )
	    rstat = EXEC_CMD_FAIL;
	else
	    rstat = EXEC_CMD_OK;

	cmdtab[ i ].pid = 0;
	/* SVA don't leak temp files */
	if(cmdtab[i].tempfile != NULL)
	{
            free(cmdtab[i].tempfile);
            cmdtab[i].tempfile = NULL;
	}
	(*cmdtab[ i ].func)( cmdtab[ i ].closure, rstat, &time );

	return 1;
}
Пример #7
0
void
execcmd( 
	char *string,
	void (*func)( void *closure, int status, timing_info* ),
	void *closure,
	LIST *shell )
{
    int pid;
    int slot;
    int raw_cmd = 0 ;
    char *argv_static[ MAXARGC + 1 ];	/* +1 for NULL */
    char **argv = argv_static;
    char *p;

    /* Check to see if we need to hack around the line-length limitation. */
    /* Look for a JAMSHELL setting of "%", indicating that the command
     * should be invoked directly */
    if ( shell && !strcmp(shell->string,"%") && !list_next(shell) )
    {
        raw_cmd = 1;
        shell = 0;
    }

    if ( !is_win95_defined )
        set_is_win95();
          
    /* Find a slot in the running commands table for this one. */
    if ( is_win95 )
    {
        /* only synchronous spans are supported on Windows 95/98 */
        slot = 0;
    }
    else
    {
        for( slot = 0; slot < MAXJOBS; slot++ )
            if( !cmdtab[ slot ].pid )
                break;
    }
    if( slot == MAXJOBS )
    {
        printf( "no slots for child!\n" );
        exit( EXITBAD );
    }
  
    if( !cmdtab[ slot ].tempfile )
    {
        const char *tempdir = path_tmpdir();
        DWORD procID = GetCurrentProcessId();
  
        /* SVA - allocate 64 other just to be safe */
        cmdtab[ slot ].tempfile = malloc( strlen( tempdir ) + 64 );
        if ( DEBUG_PROFILE )
            profile_memory( strlen( tempdir ) + 64 );
  
        sprintf( cmdtab[ slot ].tempfile, "%s\\jam%d-%02d.bat", 
                 tempdir, procID, slot );		
    }

    /* Trim leading, ending white space */

    while( isspace( *string ) )
        ++string;

    /* Write to .BAT file unless the line would be too long and it
     * meets the other spawnability criteria.
     */
    if( raw_cmd && can_spawn( string ) >= MAXLINE )
    {
        if( DEBUG_EXECCMD )
            printf("Executing raw command directly\n");        
    }
    else
    {
        FILE *f = 0;
        int tries = 0;
        raw_cmd = 0;
        
        /* Write command to bat file. For some reason this open can
           fails intermitently. But doing some retries works. Most likely
           this is due to a previously existing file of the same name that
           happens to be opened by an active virus scanner. Pointed out,
           and fix by Bronek Kozicki. */
        for (; !f && tries < 4; ++tries)
        {
            f = fopen( cmdtab[ slot ].tempfile, "w" );
            if ( !f && tries < 4 ) Sleep( 250 );
        }
        if (!f)
        {
            printf( "failed to write command file!\n" );
            exit( EXITBAD );
        }
        fputs( string, f );
        fclose( f );

        string = cmdtab[ slot ].tempfile;
        
        if( DEBUG_EXECCMD )
        {
            if (shell)
                printf("using user-specified shell: %s", shell->string);
            else
                printf("Executing through .bat file\n");
        }
    }

    /* Forumulate argv */
    /* If shell was defined, be prepared for % and ! subs. */
    /* Otherwise, use stock /bin/sh (on unix) or cmd.exe (on NT). */

    if( shell )
    {
        int i;
        char jobno[4];
        int gotpercent = 0;

        sprintf( jobno, "%d", slot + 1 );

        for( i = 0; shell && i < MAXARGC; i++, shell = list_next( shell ) )
        {
            switch( shell->string[0] )
            {
            case '%':	argv[i] = string; gotpercent++; break;
            case '!':	argv[i] = jobno; break;
            default:	argv[i] = shell->string;
            }
            if( DEBUG_EXECCMD )
                printf( "argv[%d] = '%s'\n", i, argv[i] );
        }

        if( !gotpercent )
            argv[i++] = string;

        argv[i] = 0;
    }
    else if (raw_cmd)
    {
        argv = string_to_args(string);
    }
    else
    {
        /* don't worry, this is ignored on Win95/98, see later.. */
        argv[0] = "cmd.exe";
        argv[1] = "/Q/C";		/* anything more is non-portable */
        argv[2] = string;
        argv[3] = 0;
    }

    /* Catch interrupts whenever commands are running. */

    if( !cmdsrunning++ )
        istat = signal( SIGINT, onintr );

    /* Start the command */

    /* on Win95, we only do a synchronous call */
    if ( is_win95 )
    {
        static const char* hard_coded[] =
            {
                "del", "erase", "copy", "mkdir", "rmdir", "cls", "dir",
                "ren", "rename", "move", 0
            };
          
        const char**  keyword;
        int           len, spawn = 1;
        int           result;
        timing_info time = {0,0};
          
        for ( keyword = hard_coded; keyword[0]; keyword++ )
        {
            len = strlen( keyword[0] );
            if ( strnicmp( string, keyword[0], len ) == 0 &&
                 !isalnum(string[len]) )
            {
                /* this is one of the hard coded symbols, use 'system' to run */
                /* them.. except for "del"/"erase"                            */
                if ( keyword - hard_coded < 2 )
                    result = process_del( string );
                else
                    result = system( string );

                spawn  = 0;
                break;
            }
        }
          
        if (spawn)
        {
            char**  args;
            
            /* convert the string into an array of arguments */
            /* we need to take care of double quotes !!      */
            args = string_to_args( string );
            if ( args )
            {
#if 0
                char** arg;
                fprintf( stderr, "%s: ", args[0] );
                arg = args+1;
                while ( arg[0] )
                {
                    fprintf( stderr, " {%s}", arg[0] );
                    arg++;
                }
                fprintf( stderr, "\n" );
#endif              
                result = spawnvp( P_WAIT, args[0], args );
                record_times(result, &time);
                free_argv( args );
            }
            else
                result = 1;
        }
        func( closure, result ? EXEC_CMD_FAIL : EXEC_CMD_OK, &time );
        return;
    }

    if( DEBUG_EXECCMD )
    {
        char **argp = argv;

        printf("Executing command");
        while(*argp != 0)
        {
            printf(" [%s]", *argp);
            argp++;
        }
        printf("\n");
    }

    /* the rest is for Windows NT only */
    /* spawn doesn't like quotes around the command name */
    if ( argv[0][0] == '"')
    {
        int l = strlen(argv[0]);

        /* Clobber any closing quote, shortening the string by one
         * element */
        if (argv[0][l-1] == '"')
            argv[0][l-1] = '\0';
        
        /* Move everything *including* the original terminating zero
         * back one place in memory, covering up the opening quote */
        memmove(argv[0],argv[0]+1,l);
    }
    if( ( pid = spawnvp( P_NOWAIT, argv[0], argv ) ) == -1 )
    {
        perror( "spawn" );
        exit( EXITBAD );
    }
    /* Save the operation for execwait() to find. */

    cmdtab[ slot ].pid = pid;
    cmdtab[ slot ].func = func;
    cmdtab[ slot ].closure = closure;

    /* Wait until we're under the limit of concurrent commands. */
    /* Don't trust globs.jobs alone.                            */

    while( cmdsrunning >= MAXJOBS || cmdsrunning >= globs.jobs )
        if( !execwait() )
            break;
    
    if (argv != argv_static)
    {
        free_argv(argv);
    }
}