QUARK  0.9.0
QUARK-QUeuingAndRuntimeforKernels
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
quarkos.c File Reference
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include "quark.h"
Include dependency graph for quarkos.c:

Go to the source code of this file.

Macros

#define QUARK_SUCCESS   0
#define QUARK_ERR   -1
#define QUARK_ERR_UNEXPECTED   -1
#define CONTEXT_THREADS_MAX   256
#define QUARK_GETENV(var, str)   envstr = getenv(var);
#define QUARK_CLEANENV(str)

Functions/Subroutines

void quark_warning (const char *func_name, char *msg_text)
void quark_topology_init ()
void quark_topology_finalize ()
int quark_setaffinity (int rank)
int quark_unsetaffinity (int rank)
int quark_yield ()
int quark_get_numthreads ()
int * quark_get_affthreads ()
int quark_getenv_int (char *name, int defval)

Detailed Description

This file handles the mapping from pthreads calls to windows threads QUARK is a software package provided by Univ. of Tennessee, Univ. of California Berkeley and Univ. of Colorado Denver

Version:
2.4.5
Author:
Piotr Luszczek
Mathieu Faverge
Date:
2010-11-15

Note : this file is a copy of a PLASMA file for use of QUARK alone

Definition in file quarkos.c.


Macro Definition Documentation

#define CONTEXT_THREADS_MAX   256

Definition at line 61 of file quarkos.c.

#define QUARK_CLEANENV (   str)

Definition at line 298 of file quarkos.c.

#define QUARK_ERR   -1

Definition at line 57 of file quarkos.c.

#define QUARK_ERR_UNEXPECTED   -1

Definition at line 58 of file quarkos.c.

#define QUARK_GETENV (   var,
  str 
)    envstr = getenv(var);

Definition at line 297 of file quarkos.c.

#define QUARK_SUCCESS   0

Definition at line 56 of file quarkos.c.


Function/Subroutine Documentation

int* quark_get_affthreads ( )

Definition at line 329 of file quarkos.c.

References CONTEXT_THREADS_MAX, QUARK_CLEANENV, and QUARK_GETENV.

{
char *envstr = NULL;
int i;
int *coresbind = (int *)malloc(CONTEXT_THREADS_MAX*sizeof(int));
/* Env variable does not exist, we search the system number of core */
QUARK_GETENV("QUARK_AFF_THREADS", envstr);
if ( envstr == NULL) {
for (i = 0; i < CONTEXT_THREADS_MAX; i++)
coresbind[i] = i % sys_corenbr;
}
else {
char *endptr;
int wrap = 0;
int nbr = 0;
long int val;
/* We use the content of the QUARK_AFF_THREADS env. variable */
for (i = 0; i < CONTEXT_THREADS_MAX; i++) {
if (!wrap) {
val = strtol(envstr, &endptr, 10);
if (endptr != envstr) {
coresbind[i] = (int)val;
envstr = endptr;
}
else {
/* there must be at least one entry */
if (i < 1) {
//quark_error("quark_get_affthreads", "QUARK_AFF_THREADS should have at least one entry => everything will be bind on core 0");
fprintf(stderr, "quark_get_affthreads: QUARK_AFF_THREADS should have at least one entry => everything will be bind on core 0");
coresbind[i] = 0;
i++;
}
/* there is no more values in the string */
/* the next threads are binded with a round robin policy over this array */
wrap = 1;
nbr = i;
coresbind[i] = coresbind[0];
}
}
else {
coresbind[i] = coresbind[i % nbr];
}
}
}
QUARK_CLEANENV(envstr);
/* return QUARK_SUCCESS; */
return coresbind;
}

Here is the caller graph for this function:

int quark_get_numthreads ( )

Check for an integer in an environment variable, returning the integer value or a provided default value

Definition at line 306 of file quarkos.c.

References QUARK_CLEANENV, and QUARK_GETENV.

{
char *envstr = NULL;
char *endptr;
long int thrdnbr = -1;
extern int errno;
/* Env variable does not exist, we search the system number of core */
QUARK_GETENV("QUARK_NUM_THREADS", envstr);
if ( envstr == NULL ) {
thrdnbr = sys_corenbr;
} else {
/* Convert to long, checking for errors */
thrdnbr = strtol(envstr, &endptr, 10);
if ((errno == ERANGE) || ((thrdnbr==0) && (endptr==envstr))) {
QUARK_CLEANENV(envstr);
return -1;
}
}
QUARK_CLEANENV(envstr);
return (int)thrdnbr;
}

Here is the caller graph for this function:

int quark_getenv_int ( char *  name,
int  defval 
)

Definition at line 384 of file quarkos.c.

References QUARK_CLEANENV, and QUARK_GETENV.

{
char *envstr = NULL;
char *endptr;
long int longval = -1;
extern int errno;
QUARK_GETENV(name, envstr);
if ( envstr == NULL ) {
longval = defval;
} else {
/* Convert to long, checking for errors */
longval = strtol(envstr, &endptr, 10);
if ((errno == ERANGE) || ((longval==0) && (endptr==envstr))) {
longval = defval;
}
}
QUARK_CLEANENV(envstr);
return (int)longval;
}

Here is the caller graph for this function:

int quark_setaffinity ( int  rank)

This routine will set affinity for the calling thread that has rank 'rank'. Ranks start with 0.

If there are multiple instances of QUARK then affinity will be wrong: all ranks 0 will be pinned to core 0.

Also, affinity is not resotred when QUARK_Finalize() is called.

Definition at line 129 of file quarkos.c.

References QUARK_ERR_NOT_SUPPORTED, QUARK_ERR_UNEXPECTED, and QUARK_SUCCESS.

{
#ifndef QUARK_AFFINITY_DISABLE
#if (defined QUARK_OS_LINUX)
{
cpu_set_t set;
CPU_ZERO( &set );
CPU_SET( rank, &set );
#if (defined HAVE_OLD_SCHED_SETAFFINITY)
if( sched_setaffinity( 0, &set ) < 0 )
#else /* HAVE_OLD_SCHED_SETAFFINITY */
if( sched_setaffinity( 0, sizeof(set), &set) < 0 )
#endif /* HAVE_OLD_SCHED_SETAFFINITY */
{
}
return QUARK_SUCCESS;
}
#elif (defined QUARK_OS_MACOS)
{
thread_affinity_policy_data_t ap;
int ret;
ap.affinity_tag = 1; /* non-null affinity tag */
ret = thread_policy_set( mach_thread_self(),
THREAD_AFFINITY_POLICY,
(integer_t*) &ap,
THREAD_AFFINITY_POLICY_COUNT
);
if(ret != 0)
return QUARK_SUCCESS;
}
#elif (defined QUARK_OS_WINDOWS)
{
DWORD mask = 1 << rank;
if( SetThreadAffinityMask(GetCurrentThread(), mask) == 0)
return QUARK_SUCCESS;
}
#elif (defined QUARK_OS_AIX)
{
tid_t self_ktid = thread_self ();
bindprocessor(BINDTHREAD, self_ktid, rank);
return QUARK_SUCCESS;
}
#else
#endif
#endif /* QUARK_AFFINITY_DISABLE */
}

Here is the caller graph for this function:

void quark_topology_finalize ( )

Definition at line 115 of file quarkos.c.

References quark_unsetaffinity().

Here is the call graph for this function:

Here is the caller graph for this function:

void quark_topology_init ( )

Definition at line 79 of file quarkos.c.

References pthread_mutex_lock(), and pthread_mutex_unlock().

{
pthread_mutex_lock(&mutextopo);
if ( !topo_initialized ) {
#if (defined QUARK_OS_LINUX) || (defined QUARK_OS_AIX)
sys_corenbr = sysconf(_SC_NPROCESSORS_ONLN);
#elif (defined QUARK_OS_MACOS)
int mib[4];
int cpu;
size_t len = sizeof(cpu);
/* set the mib for hw.ncpu */
mib[0] = CTL_HW;
mib[1] = HW_AVAILCPU;
/* get the number of CPUs from the system */
sysctl(mib, 2, &cpu, &len, NULL, 0);
if( cpu < 1 ) {
mib[1] = HW_NCPU;
sysctl( mib, 2, &cpu, &len, NULL, 0 );
}
if( cpu < 1 ) {
cpu = 1;
}
sys_corenbr = cpu;
#elif (defined QUARK_OS_WINDOWS)
SYSTEM_INFO sysinfo;
GetSystemInfo(&sysinfo);
sys_corenbr = sysinfo.dwNumberOfProcessors;
#endif
}
pthread_mutex_unlock(&mutextopo);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int quark_unsetaffinity ( int  rank)

This routine will set affinity for the calling thread that has rank 'rank'. Ranks start with 0.

If there are multiple instances of QUARK then affinity will be wrong: all ranks 0 will be pinned to core 0.

Also, affinity is not resotred when QUARK_Finalize() is called.

Definition at line 196 of file quarkos.c.

References QUARK_ERR_NOT_SUPPORTED, QUARK_ERR_UNEXPECTED, QUARK_SUCCESS, and quark_warning().

{
#ifndef QUARK_AFFINITY_DISABLE
#if (defined QUARK_OS_LINUX)
{
int i;
cpu_set_t set;
CPU_ZERO( &set );
for(i=0; i<sys_corenbr; i++)
CPU_SET( i, &set );
#if (defined HAVE_OLD_SCHED_SETAFFINITY)
if( sched_setaffinity( 0, &set ) < 0 )
#else /* HAVE_OLD_SCHED_SETAFFINITY */
if( sched_setaffinity( 0, sizeof(set), &set) < 0 )
#endif /* HAVE_OLD_SCHED_SETAFFINITY */
{
quark_warning("quark_unsetaffinity", "Could not unbind thread");
}
return QUARK_SUCCESS;
}
#elif (defined QUARK_OS_MACOS)
{
/* TODO: check how to unbind the main thread if necessary for OpenMP */
/* thread_affinity_policy_data_t ap; */
/* int ret; */
/* ap.affinity_tag = 1; /\* non-null affinity tag *\/ */
/* ret = thread_policy_set( mach_thread_self(), */
/* THREAD_AFFINITY_POLICY, */
/* (integer_t*) &ap, */
/* THREAD_AFFINITY_POLICY_COUNT */
/* ); */
/* if(ret != 0) { */
/* quark_warning("quark_unsetaffinity", "Could not unbind thread"); */
/* return QUARK_ERR_UNEXPECTED; */
/* } */
return QUARK_SUCCESS;
}
#elif (defined QUARK_OS_WINDOWS)
{
int i;
DWORD mask = 0;
for(i=0; i<sys_corenbr; i++)
mask |= 1 << i;
if( SetThreadAffinityMask(GetCurrentThread(), mask) == 0) {
quark_warning("quark_unsetaffinity", "Could not unbind thread");
}
return QUARK_SUCCESS;
}
#elif (defined QUARK_OS_AIX)
{
/* TODO: check how to unbind the main thread if necessary for OpenMP */
/* tid_t self_ktid = thread_self (); */
/* bindprocessor(BINDTHREAD, self_ktid, rank); */
return QUARK_SUCCESS;
}
#else
#endif
#endif /* QUARK_AFFINITY_DISABLE */
}

Here is the call graph for this function:

Here is the caller graph for this function:

void quark_warning ( const char *  func_name,
char *  msg_text 
)

Warning messages

Parameters:
[in]func_nameFunction location where warning occurred
[in]msg_textWarning message to display.

Definition at line 404 of file quark.c.

{
fprintf(stderr, "QUARK_WARNING: %s(): %s\n", func_name, msg_text);
}

Here is the caller graph for this function:

int quark_yield ( )

A thread can unlock the CPU if it has nothing to do to let another thread of less priority running for example for I/O.

Definition at line 271 of file quarkos.c.

References QUARK_ERR_NOT_SUPPORTED.

{
#if (defined QUARK_OS_LINUX) || (defined QUARK_OS_MACOS) || (defined QUARK_OS_AIX)
return sched_yield();
#elif QUARK_OS_WINDOWS
return SleepEx(0,0);
#else
#endif
}