コード例 #1
0
/**
 * see README
 */
int main(int argc, char *argv[]) {

    int c;

    static struct option long_options[] =
        {
            /* These options don't set a flag.
               We distinguish them by their indices. */
            {"summarize",         optional_argument,       0, 's'},
            {"pages",             optional_argument,       0, 'p'},
            {"only-cached",       optional_argument,       0, 'c'},
            {"graph",             optional_argument,       0, 'g'},
            {"verbose",           optional_argument,       0, 'v'},
            {"min-size",          required_argument,       0, 'S'},
            {"min-cached-size",   required_argument,       0, 'C'},
            {"min-cached-perc",   required_argument,       0, 'P'},
            {"help",              no_argument,             0, 'h'},
            {"vertical",          no_argument,             0, 'L'},
            {0, 0, 0, 0}
        };

    while (1) {

        /* getopt_long stores the option index here. */
        int option_index = 0;
        
        c = getopt_long (argc, argv, "s::p::c::g::v::L::S:C:P:h",long_options, &option_index);
        
        /* Detect the end of the options. */
        if (c == -1)
            break;
        
        //bool foo = 1;

        switch (c)
            {
            case 0:
                /* If this option set a flag, do nothing else now. */
                if (long_options[option_index].flag != 0)
                    break;
                if (optarg)
                    printf (" with arg %s", optarg);
                printf ("\n");
                break;

            case 'p':
                arg_pages = _argtobool( optarg );
                break;

            case 's':
                arg_summarize = _argtobool( optarg );
                break;
                
            case 'c':
                arg_only_cached = _argtobool( optarg );
                break;
                
            case 'g':
                arg_graph = _argtobool( optarg );
                break;

            case 'v':
                arg_verbose = _argtoint( optarg, 1 );
                break;

            case 'S':
                arg_min_size = _argtoint( optarg, 0 );
                break;

            case 'C':
                arg_min_cached_size = _argtoint( optarg, 0 );
                break;

            case 'P':
                arg_min_cached_perc = _argtoint( optarg, 0 );
                break;

            case 'L':
                arg_vertical = _argtoint( optarg, 1 );
                break;

            case 'h':
                help();
                exit(1);

            case '?':
                /* getopt_long already printed an error message. */
                break;
                
            default:

                fprintf( stderr, "Invalid command line item: %s\n" , argv[ optind ] );
                help();
                
                exit(1);
            }
    } // done processing arguments.

   if ( arg_verbose >= 1 ) {

       printf( "Running with arguments: \n" );
       printf( "    pages:            %d\n",  arg_pages );
       printf( "    summarize:        %d\n",  arg_summarize );
       printf( "    only cached:      %d\n",  arg_only_cached );
       printf( "    graph:            %d\n",  arg_graph );
       printf( "    min size:         %ld\n", arg_min_size );
       printf( "    min cached size:  %ld\n", arg_min_cached_size );
       printf( "    min cached perc:  %ld\n", arg_min_cached_perc );
       printf( "    vertical:         %ld\n", arg_vertical );

   }

    setlocale( LC_NUMERIC, "en_US" );

    nr_regions = DEFAULT_NR_REGIONS;

    struct winsize ws; 

    if (ioctl(stdout,TIOCGWINSZ,&ws) == 0) { 
        
        if ( ws.ws_col > nr_regions ) {
            nr_regions = ((ws.ws_col/2)*2) - 10;
        }

        //printf( "Using graph width: %d\n" , nr_regions );

    } 

    if ( optind == argc ) {
        help();
        exit(1);
    }

    if ( ! arg_graph ) 
        _show_headers();

    long total_cached_size = 0;
    
    /* Print any remaining command line arguments (not options). */
        
    if (optind < argc) {
        
       while (optind < argc) {
           
           char* path = argv[optind++];

            struct fincore_result result;

            fincore( path, &result );

            total_cached_size += result.cached_size;

           //printf ("%s ", );
           //putchar ('\n');
       }

   }

    if ( arg_summarize ) {
        
        printf( "---\n" );

        //TODO: add more metrics including total size... 
        printf( "total cached size: %'ld\n", total_cached_size );

    }

}
コード例 #2
0
ファイル: pgfincore.c プロジェクト: klando/pgfincore
/*
 * pgfincore_file handle the mmaping, mincore process (and access file, etc.)
 */
static int
pgfincore_file(char *filename, pgfincoreStruct *pgfncr)
{
	int		flag=1;
	int		flag_dirty=1;

	int		len, bitlen;
	bits8	*r;
	bits8	x = 0;
	register int64 pageIndex;


	/*
	 * We use the AllocateFile(2) provided by PostgreSQL.  We're going to
	 * close it ourselves even if PostgreSQL close it anyway at transaction
	 * end.
	 */
	FILE	*fp;
	int	fd;
	struct stat st;

#ifndef HAVE_FINCORE
	void 		  *pa  = (char *) 0;
#endif
	unsigned char *vec = (unsigned char *) 0;

	/*
	 * OS Page size
	 */
	pgfncr->pageSize  = sysconf(_SC_PAGESIZE);

	/*
	 * Initialize counters
	 */
	pgfncr->pages_mem		= 0;
	pgfncr->group_mem		= 0;
	pgfncr->pages_dirty		= 0;
	pgfncr->group_dirty		= 0;
	pgfncr->rel_os_pages	= 0;

	/*
	 * Fopen and fstat file
	 * fd will be provided to posix_fadvise
	 * if there is no file, just return 1, it is expected to leave the SRF
	 */
	fp = AllocateFile(filename, "rb");
	if (fp == NULL)
                return 1;

	fd = fileno(fp);

	if (fstat(fd, &st) == -1)
	{
		FreeFile(fp);
		elog(ERROR, "Can not stat object file : %s",
		     filename);
		return 2;
	}

	/*
	* if file ok
	* then process
	*/
	if (st.st_size != 0)
	{
		/* number of pages in the current file */
		pgfncr->rel_os_pages = (st.st_size+pgfncr->pageSize-1)/pgfncr->pageSize;

#ifndef HAVE_FINCORE
		pa = mmap(NULL, st.st_size, PROT_NONE, MAP_SHARED, fd, 0);
		if (pa == MAP_FAILED)
		{
			FreeFile(fp);
			elog(ERROR, "Can not mmap object file : %s, errno = %i,%s\nThis error can happen if there is not enought space in memory to do the projection. Please mail [email protected] with '[pgfincore] ENOMEM' as subject.",
			     filename, errno, strerror(errno));
			return 3;
		}
#endif

		/* Prepare our vector containing all blocks information */
		vec = calloc(1, (st.st_size+pgfncr->pageSize-1)/pgfncr->pageSize);
		if ((void *)0 == vec)
		{
#ifndef HAVE_FINCORE
			munmap(pa, st.st_size);
#endif
			FreeFile(fp);
			elog(ERROR, "Can not calloc object file : %s",
			     filename);
			return 4;
		}

#ifndef HAVE_FINCORE
		/* Affect vec with mincore */
		if (mincore(pa, st.st_size, vec) != 0)
		{
			munmap(pa, st.st_size);
			elog(ERROR, "mincore(%p, %lld, %p): %s\n",
			     pa, (long long int)st.st_size, vec, strerror(errno));
#else
		/* Affect vec with fincore */
		if (fincore(fd, 0, st.st_size, vec) != 0)
		{
			elog(ERROR, "fincore(%u, 0, %lld, %p): %s\n",
			     fd, (long long int)st.st_size, vec, strerror(errno));
#endif
			free(vec);
			FreeFile(fp);
			return 5;
		}

		/*
		 * prepare the bit string
		 */
		bitlen = FINCORE_BITS * ((st.st_size+pgfncr->pageSize-1)/pgfncr->pageSize);
		len = VARBITTOTALLEN(bitlen);
		/*
		 * set to 0 so that *r is always initialised and string is zero-padded
		 * XXX: do we need to free that ?
		 */
		pgfncr->databit = (VarBit *) palloc0(len);
		SET_VARSIZE(pgfncr->databit, len);
		VARBITLEN(pgfncr->databit) = bitlen;

		r = VARBITS(pgfncr->databit);
		x = HIGHBIT;

		/* handle the results */
		for (pageIndex = 0; pageIndex <= pgfncr->rel_os_pages; pageIndex++)
		{
			// block in memory
			if (vec[pageIndex] & FINCORE_PRESENT)
			{
				pgfncr->pages_mem++;
				*r |= x;
				if (FINCORE_BITS > 1)
				{
					if (vec[pageIndex] & FINCORE_DIRTY)
					{
						pgfncr->pages_dirty++;
						*r |= (x >> 1);
						/* we flag to detect contigous blocks in the same state */
						if (flag_dirty)
							pgfncr->group_dirty++;
						flag_dirty = 0;
					}
					else
						flag_dirty = 1;
				}