示例#1
0
static int
kflops_raw( void )
{	
	static int		kflops = -1;
	int				quick_kflops = 0;
	int				loops;

	sysapi_internal_reconfig();

	// If we haven't run before, get a quick measurement
	// For slow machines, we'll use that quick measurement
	if ( kflops < 0 ) {
		quick_kflops = clinpack_kflops( QUICK_RUNS );
	}
	else {
		quick_kflops = kflops;
	}

	// For faster machines, run with more loops.
	loops = (int) floor( 0.9999 + (QUICK_RUNS * quick_kflops * LOOP_CONST) );
# if(ENABLE_TIMING)
	double t1 = UtcTime::getTimeDouble( );
# endif

	kflops = clinpack_kflops( loops );

# if(ENABLE_TIMING)
	double t2 = UtcTime::getTimeDouble( );
	printf( "quick=%d, loops=%d, time=%0.3fs\n",
			quick_kflops, loops, t2-t1 );
# endif
	return kflops;
}
示例#2
0
float
sysapi_load_avg_raw(void)
{
  struct pst_dynamic d;
  	/* make numcpus static so we do not have to recompute
	 * numcpus every time the load average is requested.
	 * after all, the number of cpus is not going to change!
	 * we need to multiply the value the HPUX kerenel gives
	 * us by the number of CPUs, because on SMP HPUX the kernel
	 * "distributes" the load average across all CPUs.  But
	 * no other Unix does that, so our startd assumes otherwise.
	 * So we multiply by the number of CPUs so HPUX SMP load avg
	 * is reported the same way as other Unixes. -Todd
	 */
  static int numcpus = 0;  

  sysapi_internal_reconfig();
  if ( numcpus == 0 ) {
    numcpus = sysapi_ncpus();
	if ( numcpus < 1 ) {
		numcpus = 1;
	}
  }

  if ( pstat_getdynamic ( &d, sizeof(d), (size_t)1, 0) != -1 ) {
    return (d.psd_avg_1_min * numcpus);
  }
  else {
    return -1.0;
  }
}
示例#3
0
float
sysapi_load_avg_raw(void)
{

	float first, second, third;
	int mib[4];
	struct loadavg load;
	size_t len;

	sysapi_internal_reconfig();

	mib[0] = CTL_VM;
	mib[1] = VM_LOADAVG;
	len = sizeof(struct loadavg);		
	sysctl(mib, 2, &load, &len, NULL, 0);
	first = (float)load.ldavg[0] / (float)load.fscale;
	second = (float)load.ldavg[1] / (float)load.fscale;
	third = (float)load.ldavg[2] / (float)load.fscale;

	if( IsDebugVerbose( D_LOAD ) ) {
		dprintf( D_LOAD, "Load avg: %.2f %.2f %.2f\n", 
			first, second, third );
	}
	return first;
}
示例#4
0
/* the cooked version */
float
sysapi_load_avg(void)
{
	sysapi_internal_reconfig();

	if ( _sysapi_getload ) {
		return sysapi_load_avg_raw();
	} else {
		return 0.0;
	}
}
示例#5
0
/* Do not free the returned pointer */
const char *
sysapi_ckptpltfrm(void)
{	
	sysapi_internal_reconfig();

	if( _sysapi_ckptpltfrm != NULL ) {
		return _sysapi_ckptpltfrm;
	} else {
		return sysapi_ckptpltfrm_raw();
	}
}
示例#6
0
/* Do not free the returned pointer */
const char *
sysapi_kernel_version(void)
{	
	sysapi_internal_reconfig();

	if( _sysapi_kernel_version != NULL ) {
		return _sysapi_kernel_version;
	} else {
		return sysapi_kernel_version_raw();
	}
}
示例#7
0
float
sysapi_load_avg_raw(void)
{
    FILE	*proc;
	struct utsname buf;
	int		major, minor, patch;
	float	short_avg, medium_avg, long_avg;

	sysapi_internal_reconfig();

	// Obtain the kernel version so that we know what /proc looks like..
	if( uname(&buf) < 0 )  return -1;
	sscanf(buf.release, "%d.%d.%d", &major, &minor, &patch);

	// /proc/loadavg looks like:

	// Kernel Version 2.0.0:
	// 0.03 0.03 0.09 2/42 15582

    proc=safe_fopen_wrapper_follow("/proc/loadavg","r",0644);
    if(!proc)
	return -1;

	switch(major) {
		case 1:
		case 2:
		case 3:
    		if (fscanf(proc, "%f %f %f", &short_avg, &medium_avg, &long_avg) != 3) {
				dprintf(D_ALWAYS, "Failed to fscanf 3 floats from /proc/loadavg\n");
				fclose(proc);
				return -1;
			}
			break;

		default:
			dprintf(D_ALWAYS, "/proc format unknown for kernel version %d.%d.%d\n",
				major, minor, patch);
    		fclose(proc);
			return -1;
			break;
	}

    fclose(proc);

	if( IsDebugVerbose( D_LOAD ) ) {
		dprintf( D_LOAD, "Load avg: %.2f %.2f %.2f\n", short_avg, 
				 medium_avg, long_avg );
	}
	return short_avg;
}
示例#8
0
float
sysapi_load_avg_raw(void)
{

	float val;

	sysapi_internal_reconfig();
	val = lookup_load_avg_via_uptime();

	if( IsDebugVerbose( D_LOAD ) ) {
		dprintf( D_LOAD, "Load avg: %.2f\n", val );
	}
	return val;
}
示例#9
0
long long
sysapi_disk_space_raw(const char *filename)
{
	ULARGE_INTEGER FreeBytesAvailableToCaller, TotalNumberOfBytes, TotalNumberOfFreeBytes;
	unsigned int t_hi, t_lo, temp;
	const unsigned int lowest_ten_mask = 0x000003ff;
	
	t_hi = t_lo = temp = 0;
	sysapi_internal_reconfig();

	
	if (GetDiskFreeSpaceEx(filename, &FreeBytesAvailableToCaller, &TotalNumberOfBytes, 
		&TotalNumberOfFreeBytes) == 0) {
		return -1;
	} else {
#if 1
		return FreeBytesAvailableToCaller.QuadPart;
#else
		// we have to shift everything down 10 bits since we report the number
		// of kbytes free. There's a HighPart and a LowPart, so it gets a little ugly.

		// first shift the low part (divide by 1024 to get it into kbytes)
		t_lo = FreeBytesAvailableToCaller.LowPart;
		t_lo = t_lo >> 10;
		// now grab the lowest 10 bits in the high part
		t_hi = FreeBytesAvailableToCaller.HighPart;
		temp = lowest_ten_mask & t_hi;
		// shift the high part 10 bits to get it into kbytes
		t_hi = t_hi >> 10;
		
		// shift the lowest 10 bits from the high part up to the 
		// highest 10 bits, and stick them into the low part
		temp = temp << 22;
		t_lo |= temp;

		if (t_hi > 0) {
			return INT_MAX;
		} else {
			return (int)t_lo;
		}
#endif
	}
}
示例#10
0
const struct sysapi_cpuinfo *sysapi_processor_flags_raw( void ) {
    sysapi_internal_reconfig();
    
    if( _sysapi_processor_flags_raw != NULL ) {
        return &theInfo;
    }

    /* Set the default to the empty string so that if something goes wrong
       during parsing (or if /proc/cpuinfo doesn't exist), we stop trying. */
    _sysapi_processor_flags_raw = "";

    /* If we check for the null string, we could leak memory for processors
       without flags.  (We shouldn't see any, but...) */
    int foundProcessorFlags = 0;
    
    /* You can adapt this to ncpus.cpp's _SysapiProcCpuinfo for debugging. */
    FILE * fp = safe_fopen_wrapper_follow( "/proc/cpuinfo", "r", 0644 );
    dprintf( D_LOAD, "Reading from /proc/cpuinfo\n" );
    if( fp ) {
        size_t size = 128;
        char * buffer = (char *)malloc( size );
        if( buffer == NULL ) {
            EXCEPT( "Failed to allocate buffer for parsing /proc/cpuinfo.\n" );
        }            
        
        while( fgets( buffer, size, fp ) ) {
            while( strchr( buffer, '\n' ) == NULL ) {
                char * newBuffer = (char *)realloc( buffer, size + size );
                if( newBuffer == NULL ) {
                    EXCEPT( "Failed to allocate memory for a long line in /proc/cpuinfo.\n" );
                }
                buffer = newBuffer;
                
                newBuffer = buffer + strlen( buffer );
                if( ! fgets( newBuffer, size, fp ) ) {
                    /* If we fail a read before finding the end of the line,
                       something has probably gone terribly, terribly wrong. */
                    EXCEPT( "Failed to find end of line ('%s') before end of file.\n", buffer );
                    // If /proc/cpuinfo regularly terminates without a newline,
                    // we could do this instead.
                    // free( buffer );
                    // fclose( fp );
                    // return _sysapi_processor_flags_raw;
                }
                size += size;
            }

            char * colon = strchr( buffer, ':' );
            
            const char * value = "";
            const char * attribute = NULL;
            if( colon != NULL ) {
                for( unsigned int v = 1; colon[v] != '\0' && isspace( colon[v] ); ++v ) {
                    value = colon + v;
                }
                
                char * tmp = colon;
                while( isspace( *tmp ) || (*tmp == ':' ) ) {
                    *tmp = '\0';
                    --tmp;
                }
                attribute = buffer;
                
                if( strcmp( attribute, "flags" ) == 0 ) {
                    if( foundProcessorFlags == 0 ) {
                        /* This is where we assume flags fits into buffer. */
                        _sysapi_processor_flags_raw = strdup( value );
                        if( _sysapi_processor_flags_raw == NULL ) {
                            EXCEPT( "Failed to allocate memory for the raw processor flags.\n" );
                        }
                    } else {
                        if( strcmp( _sysapi_processor_flags_raw, value ) != 0 ) {
                            dprintf( D_ALWAYS, "WARNING: Processor flags '%s' and '%s' are not the same; using the former.\n", _sysapi_processor_flags_raw, value );
                        }
                    }
                    
                    foundProcessorFlags += 1;
                } else if (strcmp(attribute, "model") == 0) {
			sscanf(value, "%d", &theInfo.model_no); 
		} else if (strcmp(attribute,"cpu family") == 0) {
			sscanf(value, "%d", &theInfo.family); 
		} else if (strcmp(attribute,"cache size") == 0) {
			sscanf(value, "%d", &theInfo.cache); 
		}
            }
        }
        
        free( buffer );
        fclose( fp );
    }
    
    theInfo.processor_flags = _sysapi_processor_flags;
    return &theInfo;
}
示例#11
0
const struct sysapi_cpuinfo *sysapi_processor_flags( void ) {
    sysapi_internal_reconfig();
    
    if( _sysapi_processor_flags != NULL ) {
        return &theInfo;
    }
    
    if( _sysapi_processor_flags_raw == NULL ) {
        sysapi_processor_flags_raw();
        ASSERT(_sysapi_processor_flags_raw != NULL);
    }

    /* Which flags do we care about?  You MUST terminate this list with NULL. */
    static const char * const flagNames[] = { "avx", "avx512", "ssse3", "sse4_1", "sse4_2", NULL };

    /* Do some memory-allocation math. */
    int numFlags = 0;
    int maxFlagLength = 0;
    for( int i = 0; flagNames[i] != NULL; ++i ) {
        ++numFlags;
        int curFlagLength = strlen( flagNames[i] );
        if( curFlagLength > maxFlagLength ) { maxFlagLength = curFlagLength; }
    }

    char * currentFlag = (char *)malloc( (1 + maxFlagLength) * sizeof( char ) );
    if( currentFlag == NULL ) {
        EXCEPT( "Failed to allocate memory for current processor flag." );
    }        
    currentFlag[0] = '\0';

    /* If we track which flags we have, we can make sure the order we
       print them is the same regardless of the raw flags order. */
    const char ** flags = (const char **)malloc( sizeof( const  char * ) * numFlags );
    if( flags == NULL ) {
        EXCEPT( "Failed to allocate memory for processor flags." );
    }
    for( int i = 0; i < numFlags; ++i ) { flags[i] = ""; }

    const char * flagStart = _sysapi_processor_flags_raw;
    const char * flagEnd = _sysapi_processor_flags_raw;
    while( * flagStart != '\0' ) {
        if( * flagStart == ' ' ) { ++flagStart; continue; }

        for( flagEnd = flagStart; (* flagEnd != '\0') && (* flagEnd != ' '); ++flagEnd ) { ; }

        int flagSize = (flagEnd - flagStart) / sizeof( char );
        if( flagSize > maxFlagLength ) {
            flagStart = flagEnd;
            continue;
        }
        
        /* We know that flagStart is neither ' ' nor '\0', so we must have
           at least one character.  Because we only care about flags of a
           certain length or smaller, we know we won't overflow our buffer. */
        strncpy( currentFlag, flagStart, flagSize );
        currentFlag[flagSize] = '\0';

        for( int i = 0; flagNames[i] != NULL; ++i ) {
            if( strcmp( currentFlag, flagNames[i] ) == 0 ) {
                /* Add to the flags. */
                flags[i] = flagNames[i];            
                break;
            }
        }

        flagStart = flagEnd;
    }
    free( currentFlag );

    /* How much space do we need? */
    int flagsLength = 1;
    for( int i = 0; i < numFlags; ++i ) {
        int length = strlen( flags[i] );
        if( length ) { flagsLength += length + 1; }
    }
    
    if( flagsLength == 1 ) {
        _sysapi_processor_flags = "none";
    } else {
        char * processor_flags = (char *)malloc( sizeof( char ) * flagsLength );
        if( processor_flags == NULL ) {
            EXCEPT( "Failed to allocate memory for processor flag list." );
        }
        processor_flags[0] = '\0';

        /* This way, the flags will always print out in the same order. */
        for( int i = 0; i < numFlags; ++i ) {
            if( strlen( flags[i] ) ) {
                strcat( processor_flags, flags[i] );
                strcat( processor_flags, " " );
            }                    
        }

        /* Remove the trailing space. */
        processor_flags[ flagsLength - 2 ] = '\0';
        _sysapi_processor_flags = processor_flags;
    }
    
    free( flags );
    theInfo.processor_flags = _sysapi_processor_flags;
    return &theInfo;
}
示例#12
0
float
sysapi_load_avg_raw(void)
{
	static HANDLE threadHandle = NULL;
	static int threadID = -1;
	time_t currentTime;
	double totalLoad=0.0;
	DWORD exitCode = 0;
	BOOL createNewThread = FALSE;
	int numSamples=0, i;

	sysapi_internal_reconfig();
	
	if (threadHandle == NULL) {
		ncpus = sysapi_ncpus();
		InitializeCriticalSection(&cs);
		createNewThread = TRUE;	
	} else {
		if ( ! GetExitCodeThread( threadHandle, &exitCode ) ) {
			dprintf(D_ALWAYS, "GetExitCodeThread() failed. (err=%li)\n",
				   	GetLastError());
		} else {
			if ( exitCode != STILL_ACTIVE ) {
				// somehow the thread died, so we should get its
				// return code, dprintf it and then start a new thread.
				
				dprintf(D_ALWAYS, "loadavg thread died, restarting. "
						"(exit code=%li)\n", exitCode);
				CloseHandle(threadHandle);
				createNewThread = TRUE;
			} else {
				// thread is still alive and well. Go in peace.
				createNewThread = FALSE;
			}
		}
	}
	
	if ( createNewThread == TRUE ) {
		threadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)sample_load, 
			NULL, 0, (LPDWORD)&threadID);
		if (threadHandle == NULL) {
#ifndef TESTING
			dprintf(D_ALWAYS, "failed to create loadavg thread, errno = %d\n",
				GetLastError());
#endif
			return 0.0;
		}
		Sleep(SAMPLE_INTERVAL*5);	/* wait for ~5 samples */
	}
	
	currentTime = time(NULL);
	
	EnterCriticalSection(&cs);
	for (i=0; i < NUM_SAMPLES; i++) {
		/* if this sample occurred within the minute, then add to total */
		if ((currentTime-60) <= samples[i].sampletime) {
			totalLoad += samples[i].load;
			numSamples++;
		}
	}
	LeaveCriticalSection(&cs);

	if (numSamples == 0) {
#ifndef TESTING
		dprintf(D_ALWAYS, "no loadavg samples this minute, maybe thread died???\n");
#endif
		return 0.0;
	}

#ifndef TESTING
	dprintf(D_LOAD, "loadavg=%.2f with %d samples\n",
			((float)totalLoad)/((float)numSamples), numSamples);
#endif

	return ((float)totalLoad)/((float)numSamples);
}
示例#13
0
/* if you need to modify kflops, do it here. */
int sysapi_kflops(void)
{
	sysapi_internal_reconfig();
	return sysapi_kflops_raw();
}
示例#14
0
long long sysapi_disk_space_raw(const char * filename)
{
#if defined(Solaris)
	struct statvfs statfsbuf;
#else
	struct statfs statfsbuf;
#endif
#if 1
	long long free_kbytes;
	double kbytes_per_block;
#else
	double free_kbytes;
	float kbytes_per_block;
#endif

	sysapi_internal_reconfig();

#if defined(Solaris)
	if(statvfs(filename, &statfsbuf) < 0) {
#elif defined(AIX)
	if(statfs((char *)filename, &statfsbuf) < 0) {
#else
	if(statfs(filename, &statfsbuf) < 0) {
#endif
		if (errno != EOVERFLOW) {
			dprintf(D_ALWAYS, "sysapi_disk_space_raw: statfs(%s,%p) failed\n",
													filename, &statfsbuf );
			dprintf(D_ALWAYS, "errno = %d\n", errno );

			return(0);
		}

		// if we get here, it means that statfs failed because
		// there are more free blocks than can be represented
		// in a long.  Let's lie and make it INT_MAX - 1.

		dprintf(D_FULLDEBUG, "sysapi_disk_space_raw: statfs overflowed, setting to %d\n", (INT_MAX - 1));
		statfsbuf.f_bavail = (INT_MAX - 1);	
		statfsbuf.f_bsize = 1024; // this isn't set if result < 0, guess
	}

	/* Convert to kbyte blocks: available blks * blksize / 1k bytes. */
	/* overflow problem fixed by using doubles to hold result - 
		Keller 05/17/99 */

#if defined(Solaris)
		/* On Solaris, we need to use f_frsize, the "fundamental
		   filesystem block size", not f_bsize, the "preferred file
		   system block size".  3/25/98  Derek Wright */
	kbytes_per_block = ( (unsigned long)statfsbuf.f_frsize / 1024.0 );
#else
	kbytes_per_block = ( (unsigned long)statfsbuf.f_bsize / 1024.0 );
#endif

#if 1
	free_kbytes = (long long)(statfsbuf.f_bavail * kbytes_per_block);
#else
	free_kbytes = (double)statfsbuf.f_bavail * (double)kbytes_per_block; 
	if(free_kbytes > INT_MAX) {
		dprintf( D_ALWAYS, "sysapi_disk_space_raw: Free disk space kbytes overflow, capping to INT_MAX\n");
		return(INT_MAX);
	}
#endif

	return free_kbytes;
}
#endif

/*
  Return number of kbytes condor may play with in the named file
  system.  System administrators may reserve space which condor should
  leave alone.  This could be either a static amount of space, or an
  amount of space based on the current size of the AFS cache (or
  both).

  Note: This code assumes that if we have an AFS cache, that cache is
  on the filesystem we are asking about.  This is not true in general,
  but it is the case at the developer's home site.  A more correct
  implementation would check whether the filesystem being asked about
  is the one containing the cache.  This is messy to do if the
  filesystem name we are given isn't a full pathname, e.g.
  sysapi_disk_space("."), which is why it isn't implemented here. -- mike

*/
long long
sysapi_disk_space(const char *filename)
{
	long long answer;

	sysapi_internal_reconfig();

	answer =  sysapi_disk_space_raw(filename)
			- reserve_for_afs_cache()
			- reserve_for_fs();
	return answer < 0 ? 0 : answer;

}