[MLton-commit] r6432
spoons at mlton.org
spoons at mlton.org
Mon Mar 3 06:52:05 PST 2008
Added the Portable Linux Processor Affinity (PLPA) package
This is a subset of the PLPA package that is meant to be included in
other projects.
----------------------------------------------------------------------
U mlton/branches/shared-heap-multicore/bin/mlton-script
U mlton/branches/shared-heap-multicore/runtime/Makefile
U mlton/branches/shared-heap-multicore/runtime/cenv.h
A mlton/branches/shared-heap-multicore/runtime/plpa/
A mlton/branches/shared-heap-multicore/runtime/plpa/AUTHORS
A mlton/branches/shared-heap-multicore/runtime/plpa/LICENSE
A mlton/branches/shared-heap-multicore/runtime/plpa/Makefile
A mlton/branches/shared-heap-multicore/runtime/plpa/NEWS
A mlton/branches/shared-heap-multicore/runtime/plpa/README
A mlton/branches/shared-heap-multicore/runtime/plpa/README.mlton
A mlton/branches/shared-heap-multicore/runtime/plpa/VERSION
A mlton/branches/shared-heap-multicore/runtime/plpa/plpa.h
A mlton/branches/shared-heap-multicore/runtime/plpa/plpa_api_probe.c
A mlton/branches/shared-heap-multicore/runtime/plpa/plpa_bottom.h
A mlton/branches/shared-heap-multicore/runtime/plpa/plpa_dispatch.c
A mlton/branches/shared-heap-multicore/runtime/plpa/plpa_internal.h
----------------------------------------------------------------------
Modified: mlton/branches/shared-heap-multicore/bin/mlton-script
===================================================================
--- mlton/branches/shared-heap-multicore/bin/mlton-script 2008-03-03 14:42:04 UTC (rev 6431)
+++ mlton/branches/shared-heap-multicore/bin/mlton-script 2008-03-03 14:52:04 UTC (rev 6432)
@@ -82,7 +82,7 @@
-cc-opt-quote "-I$lib/include" \
-cc-opt '-O1' \
-cc-opt '-fno-strict-aliasing -fomit-frame-pointer -w' \
- -link-opt '-lgdtoa -lm -lgmp' \
+ -link-opt '-lgdtoa -lm -lgmp -lpthread -lplpa_included -lrt' \
-mlb-path-map "$lib/mlb-path-map" \
-target-as-opt amd64 '-m64 -mtune=opteron' \
-target-cc-opt amd64 '-m64 -mtune=opteron' \
Modified: mlton/branches/shared-heap-multicore/runtime/Makefile
===================================================================
--- mlton/branches/shared-heap-multicore/runtime/Makefile 2008-03-03 14:42:04 UTC (rev 6431)
+++ mlton/branches/shared-heap-multicore/runtime/Makefile 2008-03-03 14:52:04 UTC (rev 6432)
@@ -107,7 +107,7 @@
CC := gcc -std=gnu99
CPPFLAGS :=
-CFLAGS := -I. -Iplatform $(FLAGS)
+CFLAGS := -I. -Iplatform -Iplpa $(FLAGS)
OPTCFLAGS := $(CFLAGS) $(OPTFLAGS)
DEBUGCFLAGS := $(CFLAGS) -DASSERT=1 $(DEBUGFLAGS)
GCOPTCFLAGS = $(GCOPTFLAGS)
@@ -227,7 +227,7 @@
$(foreach f, $(basename $(BASISCFILES)), $(f)-gdb.o)
endif
-ALL := libgdtoa.a libmlton.a libmlton-gdb.a
+ALL := libgdtoa.a libplpa_included.a libmlton.a libmlton-gdb.a
ALL += gen/c-types.sml gen/basis-ffi.sml
ifeq ($(OMIT_BYTECODE), yes)
else
@@ -255,6 +255,13 @@
gdtoa/arith.h: gdtoa/arithchk.out
cd gdtoa && ./arithchk.out >arith.h
+libplpa_included.a: plpa/plpa_api_probe.c plpa/plpa_dispatch.c
+ @rm -f $@
+ cd plpa && $(CC) $(OPTCFLAGS) -c plpa_api_probe.c
+ cd plpa && $(CC) $(OPTCFLAGS) -c plpa_dispatch.c
+ $(AR) $@ plpa/*.o
+ $(RANLIB) $@
+
libmlton.a: $(OBJS)
$(AR) libmlton.a $(OBJS)
$(RANLIB) libmlton.a
Modified: mlton/branches/shared-heap-multicore/runtime/cenv.h
===================================================================
--- mlton/branches/shared-heap-multicore/runtime/cenv.h 2008-03-03 14:42:04 UTC (rev 6431)
+++ mlton/branches/shared-heap-multicore/runtime/cenv.h 2008-03-03 14:52:04 UTC (rev 6432)
@@ -40,6 +40,7 @@
#include <limits.h>
// #include <locale.h>
#include <math.h>
+#include <plpa.h>
// #include <setjmp.h>
#include <signal.h>
#include <stdarg.h>
Added: mlton/branches/shared-heap-multicore/runtime/plpa/AUTHORS
===================================================================
--- mlton/branches/shared-heap-multicore/runtime/plpa/AUTHORS 2008-03-03 14:42:04 UTC (rev 6431)
+++ mlton/branches/shared-heap-multicore/runtime/plpa/AUTHORS 2008-03-03 14:52:04 UTC (rev 6432)
@@ -0,0 +1,13 @@
+PLPA Authors
+============
+
+The IDs in parenthesis are those used in Subversion commit notices.
+
+Current Authors
+---------------
+
+Indiana University:
+- Jeff Squyres (jsquyres)
+
+Lawrence Berkeley National Lab:
+- Paul Hargrove (phargrov)
Added: mlton/branches/shared-heap-multicore/runtime/plpa/LICENSE
===================================================================
--- mlton/branches/shared-heap-multicore/runtime/plpa/LICENSE 2008-03-03 14:42:04 UTC (rev 6431)
+++ mlton/branches/shared-heap-multicore/runtime/plpa/LICENSE 2008-03-03 14:52:04 UTC (rev 6432)
@@ -0,0 +1,54 @@
+Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana
+ University Research and Technology
+ Corporation. All rights reserved.
+Copyright (c) 2004-2005 The Regents of the University of California.
+ All rights reserved.
+
+Portions copyright:
+
+Copyright (c) 2004-2005 The University of Tennessee and The University
+ of Tennessee Research Foundation. All rights
+ reserved.
+Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
+ University of Stuttgart. All rights reserved.
+
+$COPYRIGHT$
+
+Additional copyrights may follow
+
+$HEADER$
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+- Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+- Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer listed
+ in this license in the documentation and/or other materials
+ provided with the distribution.
+
+- Neither the name of the copyright holders nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+The copyright holders provide no reassurances that the source code
+provided does not infringe any patent, copyright, or any other
+intellectual property rights of third parties. The copyright holders
+disclaim any liability to any recipient for claims brought against
+recipient by any third party for infringement of that parties
+intellectual property rights.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Added: mlton/branches/shared-heap-multicore/runtime/plpa/Makefile
===================================================================
--- mlton/branches/shared-heap-multicore/runtime/plpa/Makefile 2008-03-03 14:42:04 UTC (rev 6431)
+++ mlton/branches/shared-heap-multicore/runtime/plpa/Makefile 2008-03-03 14:52:04 UTC (rev 6432)
@@ -0,0 +1,10 @@
+
+SRC = plpa_api_probe.c plpa_dispatch.c
+OBJ = ${SRC:%.c=%.o}
+
+%.o : %.c
+ gcc -DHAVE_CONFIG_H -I. -g -c $< -fPIC -DPIC -o $@;
+
+libplpa_included.a: ${OBJ}
+ ar cru $@ $<;
+ ranlib $@;
Added: mlton/branches/shared-heap-multicore/runtime/plpa/NEWS
===================================================================
--- mlton/branches/shared-heap-multicore/runtime/plpa/NEWS 2008-03-03 14:42:04 UTC (rev 6431)
+++ mlton/branches/shared-heap-multicore/runtime/plpa/NEWS 2008-03-03 14:52:04 UTC (rev 6432)
@@ -0,0 +1,59 @@
+Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana
+ University Research and Technology
+ Corporation. All rights reserved.
+Copyright (c) 2004-2005 The Regents of the University of California.
+ All rights reserved.
+$COPYRIGHT$
+
+Additional copyrights may follow
+
+$HEADER$
+
+===========================================================================
+
+This file contains the main features as well as overviews of specific
+bug fixes (and other actions) for each version of PLPA since
+version 1.0.
+
+1.0.3
+-----
+
+- Resolve some sizing / units ambiguities that mistakenly did not make
+ it into 1.0.1. Thanks to Bert Wesarg for pointing these problems out.
+
+
+1.0.2
+-----
+
+- Ensure that plpa_sched_[set|get]affinity() returns 0 upon success.
+ Thanks to David Creasy for bringing this to our attention.
+
+
+1.0.1
+-----
+
+- Specify that cpusetsize should be in units of bytes and add some
+ missing "* 8"'s in plpa_dispatch.c.
+
+
+1.0
+---
+
+- Initial release.
+
+
+0.9a2
+-----
+
+- Change the back-end type of the plpa_bitmask_t to unsigned long
+ instead of unsigned char to avoid an endian problem.
+- No longer attempt to set the affinity in plpa_api_probe() to avoid a
+ possible race condition (setting it after getting it).
+- Fix PLPA_CPU_ZERO macro. Thanks to Bogdan Costescu for pointing
+ this out.
+
+
+0.9a1
+-----
+
+Initial public release.
Added: mlton/branches/shared-heap-multicore/runtime/plpa/README
===================================================================
--- mlton/branches/shared-heap-multicore/runtime/plpa/README 2008-03-03 14:42:04 UTC (rev 6431)
+++ mlton/branches/shared-heap-multicore/runtime/plpa/README 2008-03-03 14:52:04 UTC (rev 6432)
@@ -0,0 +1,460 @@
+Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana
+ University Research and Technology
+ Corporation. All rights reserved.
+Copyright (c) 2004-2005 The University of Tennessee and The University
+ of Tennessee Research Foundation. All rights
+ reserved.
+Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
+ University of Stuttgart. All rights reserved.
+Copyright (c) 2004-2005 The Regents of the University of California.
+ All rights reserved.
+$COPYRIGHT$
+
+Additional copyrights may follow
+
+$HEADER$
+
+===========================================================================
+
+This is the Portable Linux Processor Affinity (PLPA) package
+(pronounced "pli-pa"). It is intended for developers who wish to use
+Linux processor affinity via the sched_setaffinity() and
+sched_getaffinity() library calls, but don't want to wade through the
+morass of 3 different APIs that have been offered through the life of
+these calls in various Linux distributions and glibc versions.
+
+Specifically, to compile for any given Linux system, you need some
+complex compile-time tests to figure out which of the 3 APIs to use.
+And if you want your application to be binary portable across
+different Linux distributions, more complex run-time tests (and horrid
+compile-time trickery) are required to figure out which API the system
+you are running on uses.
+
+These problems all stem from the fact that the same 2 symbols have had
+three different APIs (with different numbers and types of
+parameters) throughout their life in Linux. Ick.
+
+The PLPA is an attempt to solve this problem by providing a single API
+that developers can write to. It provides two things:
+
+1. A single API that developers can write to, regardless of what
+ back-end API the system you are compiling on has.
+2. A run-time test and dispatch that will invoke the Right back-end
+ API depending on what back-end API the system you are running on
+ has.
+
+This package is actually pretty small. It does not attempt to have
+many extra bells and whistles. Anyone could write it and package it.
+We did it simply because it appears that no one else has yet done
+this. In a world where larger scale SMPs are [again] becoming more
+common, particularly where at least some of them are NUMA-based
+architectures, processor affinity is going to become more and more
+important. Just because developers have not yet realized that they
+have this problem does not mean that they won't evenutally figure it
+out. :-)
+
+Note that if you're looking into processor affinity, if you're on a
+NUMA machine, you probably also want to look into libnuma:
+
+ ftp://ftp.suse.com/pub/people/ak/numa/
+
+We hope that PLPA helps you.
+
+===========================================================================
+
+What, exactly, is the problem?
+------------------------------
+
+There are at least 3 different ways that sched_setaffinity is
+implemented in glibc (only one of which is documented in the
+sched_setaffinity(2) man page), and some corresponding changes
+to what the kernel considers to be valid arguments:
+
+1. int sched_setaffinity(pid_t pid, unsigned int len, unsigned
+ long *mask);
+
+This originated in the time period of 2.5 kernels and some distros
+back-ported it to their 2.4 kernels and libraries. It's unknown if
+this version was ever packaged with any 2.6 kernels.
+
+2. int sched_setaffinity (pid_t __pid, size_t __cpusetsize,
+ const cpu_set_t *__cpuset);
+
+This appears to be in recent distors using 2.6 kernels. We don't
+know exactly when #1 changed into #2. However, this prototype is nice
+because the cpu_set_t type is accompanied by fdset-like CPU_ZERO(),
+CPU_SET(), CPU_ISSET(), etc. macros.
+
+3. int sched_setaffinity (pid_t __pid, const cpu_set_t *__mask);
+
+(note the missing len parameter) This is in at least some Linux
+distros (e.g., MDK 10.0 with a 2.6.3 kernel, and SGI Altix, even
+though the Altix uses a 2.4-based kernel and therefore likely
+back-ported the 2.5 work or originated it in the first place).
+Similar to #2, the cpu_set_t type is accompanied by fdset-like
+CPU_ZERO(), CPU_SET(), CPU_ISSET(), etc. macros.
+
+But wait, it gets worse.
+
+Remember that getting/setting processor affinity has to involve the
+kernel. The sched_[sg]etaffinity() glibc functions typically do a
+little error checking and then make a syscall down into the kernel to
+actually do the work. There are multiple possibilities for problems
+here as the amount of checking has changed:
+
+1. The glibc may support the affinity functions, but the kernel may
+ not (and vice versa).
+
+ This is typically only an issue with slightly older Linux distributions.
+ Mandrake 9.2 is an example of this. PLPA can detect this at run-time
+ and turn its internal functions into no-ops and return appropriate error
+ codes (ENOSYS).
+
+2. The glibc affinity functions may be buggy (i.e., they pass bad data
+ down to the syscall).
+
+ This is fortunately restricted to some older versions of glibc, and
+ is relatively easy to check for at run-time. PLPA reliably detects
+ this situation at run-time and returns appropriate error codes
+ (ENOSYS).
+
+ The original SuSE 9.1 version seems to have this problem, but it was
+ fixed it somewhere in the SuSE patching history (it is unknown exactly
+ when). Specifically, updating to the latest SuSE 9.1 patch level
+ (as of Dec 2005) seems to fix the problem.
+
+3. The CPU_* macros for manipulating cpu_set_t bitmasks may not
+ compile because of typo bugs in system header files.
+
+ PLPA avoids this problem by providing its own PLPA_CPU_* macros for
+ manipulating CPU bitmasks. See "How do I use PLPA?", below, for
+ more details.
+
+The PLPA avoids all the glibc issues by using syscall() to directly
+access the kernel set and get affinity functions. This is described
+below.
+
+===========================================================================
+
+How does PLPA work?
+-------------------
+
+Jeff Squyres initially sent a mail to the Open MPI developer's mailing
+list explaining the Linux processor affinity problems and asking for
+help coming up with a solution (particularly for binary
+compatibility):
+
+ http://www.open-mpi.org/community/lists/devel/2005/11/0558.php
+
+Discussion on that thread and others eventually resulted in the
+run-time tests that form the heart of the PLPA. Many thanks to Paul
+Hargrove and Bogdan Costescu for their time and effort to get these
+tests right.
+
+PLPA was written so that other developers who want to use processor
+affinity in Linux don't have to go through this mess. The PLPA
+provides a single interface that can be used on any platform,
+regardless of which back-end API variant it has. This includes both
+the sched_setaffinity() and sched_getaffinity() calls as well as the
+CPU_*() macros.
+
+The PLPA avoids glibc altogether -- although tests were developed that
+could *usually* figure out which glibc variant to use at run time,
+there were still some cases where it was either impossible to
+determine or the glibc interface itself was buggy. Hence, it was
+decided that a simpler approach was simply to use syscall() to invoke
+the back-end kernel functions directly.
+
+The kernel functions have gone through a few changes as well, so the
+PLPA does a few run-time tests to determine which variant to use
+before actually invoking the back-end functions with the
+user-specified arguments.
+
+NOTE: The run-time tests that the PLPA performs involve getting the
+current affinity for the process in question and then attempting to
+set them back to the same value. By definition, this introduces a
+race condition (there is no atomic get-and-set functionality for
+processor affinity). The PLPA cannot guarantee consistent results if
+multiple entites (such as multiple threads or multiple processes) are
+setting the affinity for a process at the same time. In a worst case
+scenario, the PLPA may actually determine that it cannot determine the
+kernel variant at run time if another entity modifies a process'
+affinity while PLPA is executing its run-time tests.
+
+===========================================================================
+
+Does PLPA make truly portable binaries?
+---------------------------------------
+
+As much as Linux binaries are portable, yes. That is, if you have
+within your power to make a binary that is runnable on several
+different Linux distributions/versions/etc., then you may run into
+problems with the Linux processor affinity functions. PLPA attempts
+to solve this problem for you by *also* making the Linux processor
+affinity calls be binary portable.
+
+Hence, you need to start with something that is already binary
+portable (perhaps linking everything statically) -- then PLPA will be
+of help to you. Do not fall into the misconception that PLPA will
+magically make your executable be binary portable between different
+Linux variants.
+
+===========================================================================
+
+How do I use PLPA?
+------------------
+
+There are two main uses of the PLPA:
+
+1. Using the plpa_info executable to check if your system supports
+ processor affinity and the PLPA can determine which to use at run-time.
+2. Developers using the PLPA library to enable source and binary Linux
+ processor affinity portability.
+
+In more detail:
+
+1. The plpa_info executable is a simple call into the PLPA library
+ that checks which API variant the system it is running on has. If
+ the kernel supports processor affinity and the PLPA is able to
+ figure out which API variant to use, it prints "PLPA_PROBE_OK".
+ Other responses indicate an error.
+
+ Since the PLPA library abstracts this kind of problem away, this is
+ more a diagnostic tool than anything else. Note that plpa_info is
+ *only* compiled and installed if PLPA is installed as a standalone
+ package (see below).
+
+2. Developers can use this package by including the <plpa.h> header
+ file and using the following prototypes:
+
+ int plpa_sched_setaffinity(pid_t pid, size_t cpusetsize,
+ const plpa_cpu_set_t *cpuset);
+
+ int plpa_sched_getaffinity(pid_t pid, size_t cpusetsize,
+ const plpa_cpu_set_t *cpuset)
+
+ These functions perform run-time tests to determine which back-end
+ API variant exists on the system and then dispatch to it correctly.
+ The units of cpusetsize is number of bytes. This should normally
+ just be sizeof(*cpuset), but is made available as a parameter to
+ allow for future expansion of the PLPA (stay tuned).
+
+ The observant reader will notice that this is remarkably similar to
+ the one of the Linux API's (the function names are different and
+ the CPU set type is different). PLPA also provides several macros
+ for manipulating the plpa_cpu_set_t bitmask, quite similar to FDSET
+ macros (see "What, Exactly, Is the Problem?" above for a
+ description of problems with the native CPU_* macros):
+
+ - PLPA_CPU_ZERO(&cpuset): Sets all bits in a plpa_cpu_set_t to
+ zero.
+ - PLPA_CPU_SET(num, &cpuset): Sets bit <num> of <cpuset> to one.
+ - PLPA_CPU_CLR(num, &cpuset): Sets bit <num> of <cpuset> to zero.
+ - PLPA_CPU_ISSET(num, &cpuset): Returns one if bit <num> of
+ <cpuset> is one; returns zero otherwise.
+
+ Note that all four macros take a *pointer* to a plpa_cpu_set_t, as
+ denoted by "&cpuset" in the descriptions above.
+
+===========================================================================
+
+How do I compile / install the PLPA as a standalone package?
+------------------------------------------------------------
+
+The PLPA uses the standard GNU Autoconf/Automake/Libtool toolset to
+build and install itself. This means that generally, the following
+works:
+
+shell$ ./configure --prefix=/where/you/want/to/install
+[...lots of output...]
+shell$ make all
+[...lots of output...]
+shell$ make install
+
+Depending on your --prefix, you may need to run the "make install"
+step as root or some other privileged user.
+
+"make install" will install the following:
+
+- <plpa.h> in $includedir (typically $prefix/include)
+- libplpa.la and libplpa.a and/or libplpa.so in $libdir (typically
+ $prefix/lib)
+- plpa_info executable in $bindir (typically $prefix/bin)
+
+Note that since PLPA builds itself with GNU Libtool, it can be built
+as a static or shared library (or both). The default is to build a
+shared library. You can enable building a static library by supplying
+the "--enable-static" argument to configure; you can disable building
+the shared library by supplying the "--enable-shared" argument to
+configure. "make install" will install whichever library was built
+(or both).
+
+"make uninstall" will fully uninstall PLPA from the prefix directory
+(again, depending in filesystem permissions, you may need to run this
+as root or some privileged user).
+
+===========================================================================
+
+How do I include PLPA in my software package?
+---------------------------------------------
+
+It can be desirable to include PLPA in a larger software package
+(be sure to check out the LICENSE file) so that users don't have to
+separately download and install it before installing your software
+(after all, PLPA is a tiny little project -- why make users bother
+with it?).
+
+When used in "included" mode, PLPA will:
+
+- not install any header files
+- not build or install plpa_info
+- not build libplpa.* -- instead, it will build libplpa_included.*
+
+There are two ways to put PLPA into "included" mode. From the
+configure command line:
+
+shell$ ./configure --enable-included-mode ...
+
+Or by directly integrating PLPA's m4 configure macro in your configure
+script and invoking a specific macro to enable the included mode.
+
+Every project is different, and there are many different ways of
+integrating PLPA into yours. What follows is *one* example of how to
+do it.
+
+Copy the PLPA directory in your source tree and include the plpa.m4
+file in your configure script -- perhaps with the following line in
+acinclude.m4 (assuming the use of Automake):
+
+m4_include(path/to/plpa.m4)
+
+The following macros can then be used from your configure script:
+
+- PLPA_INIT(action-upon-success, action-upon-failure)
+ Invoke the PLPA tests and setup the PLPA to build. A traversal of
+ "make" into the PLPA directory should build everything (it is safe
+ to list the PLPA directory in the SUBDIRS of a higher-level
+ Makefile.am, for example).
+
+- PLPA_STANDALONE
+ Force the building of PLPA in standalone mode. Overrides the
+ --enable-included-mode command line switch.
+
+- PLPA_INCLUDED
+ Force the building of PLPA in included mode.
+
+- PLPA_SET_SYMBOL_PREFIX(foo)
+ Tells the PLPA to prefix all types and public symbols with "foo"
+ instead of "plpa_". This is recommended behavior if you are
+ including PLPA in a larger project -- it is possible that your
+ software will be combined with other software that also includes
+ PLPA. If you both use different symbol prefixes, there will be no
+ type/symbol clashes, and everything will compile and link
+ successfully. If you both include PLPA and do not change the symbol
+ prefix, it is likely that you will get multiple symbol definitions
+ when linking.
+
+Here's an example of integrating with a larger project named sandbox:
+
+shell$ cd sandbox
+shell$ cp -r /somewhere/else/plpa-1.0 .
+shell$ edit acinclude.m4
+...add the line "m4_include(plpa-1.0/config/plpa.m4)"...
+shell$ edit Makefile.am
+...add "plpa-1.0" to SUBDIRS...
+...add "$(top_builddir)/plpa-1.0/src/libplpa/libplpa_included.la" to
+ my executable's LDADD line...
+shell$ edit configure.ac
+...add "PLPA_INCLUDED" line...
+...add "PLPA_SET_SYMBOL_PREFIX(sandbox_plpa_)" line...
+...add "PLPA_INIT(plpa_happy=yes, plpa_happy=no)" line...
+...add error checking for plpa_happy=no case...
+shell$ edit src/my_program.c
+...add #include <plpa.h>...
+...add calls to plpa_sched_setaffinity()...
+shell$ aclocal
+shell$ autoconf
+shell$ libtoolize --automake
+shell$ automake -a
+shell$ ./configure
+...lots of output...
+shell$ make
+...lots of output...
+
+===========================================================================
+
+How can I tell if PLPA is working?
+----------------------------------
+
+Run plpa_info; if it says "PLPA_PROBE_OK", then PLPA is working
+properly.
+
+If you want to compile your own test program to verify it, try
+compiling and running the following:
+
+---------------------------------------------------------------------------
+#include <stdio.h>
+#include <plpa.h>
+
+int main(int argc, char* argv[]) {
+ if (PLPA_PROBE_OK == plpa_api_probe()) {
+ printf("All is good!\n");
+ }
+ return 0;
+}
+---------------------------------------------------------------------------
+
+You may need to supply appropriate -I and -L arguments to the
+compiler/linker, respectively, to tell it where to find the PLPA
+header and library files. Also don't forget to supply -lplpa to link
+in the PLPA library itself. For example, if you configured PLPA with:
+
+shell$ ./configure --prefix=$HOME/my-plpa-install
+
+Then you would compile the above program with:
+
+shell$ gcc my-plpa-test.c \
+ -I$HOME/my-plpa-install/include \
+ -L$HOME/my-plpa-install/lib -lplpa \
+ -o my-plpa-test
+shell$ ./my-plpa-test
+
+If it compiles, links, runs, and prints "All is good!", then all
+should be well.
+
+===========================================================================
+
+What license does PLPA use?
+---------------------------
+
+This package is distributed under the BSD license (see the LICENSE
+file in the top-level directory of a PLPA distribution). The
+copyrights of several institutions appear throughout the code base
+because some of the code was directly derived from the Open MPI
+project (http://www.open-mpi.org/), which is also distributed under
+the BSD license.
+
+===========================================================================
+
+How do I get involved in PLPA?
+------------------------------
+
+Hopefully, PLPA is so simple that it won't need to be modified much
+after its first few releases. However, it is possible that we'll need
+to modify the run-time test if new variants of the Linux processor
+affinity API emerge.
+
+The best way to report bugs, send comments, or ask questions is to
+sign up on the user's mailing list:
+
+ plpa-users at open-mpi.org
+
+Because of spam, only subscribers are allowed to post to this list
+(ensure that you subscribe with and post from exactly the same e-mail
+address -- joe at example.com is considered different than
+joe at mycomputer.example.com!). Visit this page to subscribe to the
+list:
+
+ http://www.open-mpi.org/mailman/listinfo.cgi/plpa-users
+
+Thanks for your time.
Added: mlton/branches/shared-heap-multicore/runtime/plpa/README.mlton
===================================================================
--- mlton/branches/shared-heap-multicore/runtime/plpa/README.mlton 2008-03-03 14:42:04 UTC (rev 6431)
+++ mlton/branches/shared-heap-multicore/runtime/plpa/README.mlton 2008-03-03 14:52:04 UTC (rev 6432)
@@ -0,0 +1,3 @@
+
+XXX spoons add readme
+
Added: mlton/branches/shared-heap-multicore/runtime/plpa/VERSION
===================================================================
--- mlton/branches/shared-heap-multicore/runtime/plpa/VERSION 2008-03-03 14:42:04 UTC (rev 6431)
+++ mlton/branches/shared-heap-multicore/runtime/plpa/VERSION 2008-03-03 14:52:04 UTC (rev 6432)
@@ -0,0 +1,36 @@
+# This is the VERSION file for PLPA, describing the precise version of
+# PLPA in this distribution. The various components of the version
+# number below are combined to form a single version number string.
+
+# major, minor, and release are generally combined in the form
+# <major>.<minor>.<release>. If release is zero, then it is omitted.
+
+major=1
+minor=0
+release=3
+
+# greek is used for alpha or beta release tags. If it is non-empty,
+# it will be appended to the version number. It does not have to be
+# numeric. Common examples include a1 (alpha release 1), b1 (beta
+# release 1), sc2005 (Super Computing 2005 release). The only
+# requirement is that it must be entirely printable ASCII characters
+# and have no white space.
+
+greek=
+
+# If want_svn=1, then the SVN r number will be included in the overall
+# PLPA version number in some form.
+
+want_svn=0
+
+# If svn_r=-1, then the SVN r numbere will be obtained dynamically at
+# run time, either 1) via the "svnversion" command (if this is a
+# Subversion checkout) in the form "r<svn_r>", or b) with the date (if
+# this is not a Subversion checkout, and the svnversion command cannot
+# be used) in the form of "svn<date>". Alternatively, if svn_r is not
+# -1, the value of svn_r will be directly appended to the version
+# string. This happens during "make dist", for example: if the
+# distribution tarball is being made from an SVN checkout, the value
+# of svn_r in this file is replaced with the output of "svnversion".
+
+svn_r=r58
Added: mlton/branches/shared-heap-multicore/runtime/plpa/plpa.h
===================================================================
--- mlton/branches/shared-heap-multicore/runtime/plpa/plpa.h 2008-03-03 14:42:04 UTC (rev 6431)
+++ mlton/branches/shared-heap-multicore/runtime/plpa/plpa.h 2008-03-03 14:52:04 UTC (rev 6432)
@@ -0,0 +1,78 @@
+/* src/libplpa/plpa.h. Generated by configure. */
+/* src/libplpa/plpa.h.in. Generated from configure.ac by autoheader. */
+
+/* -*- c -*-
+ *
+ * Copyright (c) 2004-2005 The Trustees of Indiana University.
+ * All rights reserved.
+ * Copyright (c) 2004-2005 The Regents of the University of California.
+ * All rights reserved.
+ * $COPYRIGHT$
+ *
+ * Additional copyrights may follow
+ *
+ * $HEADER$
+ */
+
+#ifndef PLPA_H
+#define PLPA_H
+
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if your C compiler doesn't accept -c and -o together. */
+/* #undef NO_MINUS_C_MINUS_O */
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "http://www.open-mpi.org/community/help/"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "plpa"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "plpa 1.0.1a1"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "plpa"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "1.0.1a1"
+
+/* The PLPA symbol prefix */
+#define PLPA_SYM_PREFIX plpa_
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+
+#include "plpa_bottom.h"
+#endif /* PLPA_H */
+
Added: mlton/branches/shared-heap-multicore/runtime/plpa/plpa_api_probe.c
===================================================================
--- mlton/branches/shared-heap-multicore/runtime/plpa/plpa_api_probe.c 2008-03-03 14:42:04 UTC (rev 6431)
+++ mlton/branches/shared-heap-multicore/runtime/plpa/plpa_api_probe.c 2008-03-03 14:52:04 UTC (rev 6432)
@@ -0,0 +1,65 @@
+/* -*- c -*-
+ *
+ * Copyright (c) 2004-2005 The Trustees of Indiana University.
+ * All rights reserved.
+ * Copyright (c) 2004-2005 The Regents of the University of California.
+ * All rights reserved.
+ * $COPYRIGHT$
+ *
+ * Additional copyrights may follow
+ *
+ * $HEADER$
+ */
+
+#include <plpa.h>
+#include <errno.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+/* Cache, just to make things a little more efficient */
+static PLPA_NAME(api_type_t) cache = PLPA_PROBE_UNSET;
+
+/* The len value we find - not in public header, but used by the lib */
+size_t PLPA_NAME(len) = 0;
+
+PLPA_NAME(api_type_t) PLPA_NAME(api_probe)(void)
+{
+ if (PLPA_PROBE_UNSET == cache) {
+ PLPA_NAME(cpu_set_t) mask;
+ int rc;
+ size_t len;
+
+ for (len = sizeof(mask); len != 0; len >>= 1) {
+ rc = syscall(__NR_sched_getaffinity, 0, len, &mask);
+ if (rc >= 0) {
+ /* OK, kernel is happy with a get(). Validate w/ a set(). */
+ /* Note that kernel may have told us the "proper" size */
+ size_t tmp = (0 != rc) ? ((size_t) rc) : len;
+ /* Pass mask=NULL, expect errno==EFAULT if tmp was OK as a length */
+ rc = syscall(__NR_sched_setaffinity, 0, tmp, NULL);
+ if ((rc < 0) && (errno == EFAULT)) {
+ cache = PLPA_PROBE_OK;
+ PLPA_NAME(len) = tmp;
+ rc = 0;
+ break;
+ }
+ }
+ if (errno == ENOSYS) {
+ break; /* No point in looping */
+ }
+ }
+
+ if (rc >= 0) {
+ /* OK */
+ } else if (errno == ENOSYS) {
+ /* Kernel returns ENOSYS because there is no support for
+ processor affinity */
+ cache = PLPA_PROBE_NOT_SUPPORTED;
+ } else {
+ /* Unknown! */
+ cache = PLPA_PROBE_UNKNOWN;
+ }
+ }
+
+ return cache;
+}
Added: mlton/branches/shared-heap-multicore/runtime/plpa/plpa_bottom.h
===================================================================
--- mlton/branches/shared-heap-multicore/runtime/plpa/plpa_bottom.h 2008-03-03 14:42:04 UTC (rev 6431)
+++ mlton/branches/shared-heap-multicore/runtime/plpa/plpa_bottom.h 2008-03-03 14:52:04 UTC (rev 6432)
@@ -0,0 +1,96 @@
+/* -*- c -*-
+ *
+ * Copyright (c) 2004-2005 The Trustees of Indiana University.
+ * All rights reserved.
+ * Copyright (c) 2004-2005 The Regents of the University of California.
+ * All rights reserved.
+ * $COPYRIGHT$
+ *
+ * Additional copyrights may follow
+ *
+ * $HEADER$
+ */
+
+#ifndef PLPA_BOTTOM_H
+#define PLPA_BOTTOM_H
+
+/* Absolutely must not include <sched.h> here or it will generate
+ conflicts. */
+
+/* For memset() */
+#include <string.h>
+/* For pid_t and size_t */
+#include <sys/types.h>
+
+/***************************************************************************/
+
+/* Internal macro to munge names */
+
+/* Preprocessors are fun -- the double inderection is necessary.
+ Extra bonus points if you can figure out why! :p */
+#define PLPA_MUNGE_NAME(a, b) PLPA_MUNGE_NAME2(a, b)
+#define PLPA_MUNGE_NAME2(a, b) a ## b
+#define PLPA_NAME(name) PLPA_MUNGE_NAME(PLPA_SYM_PREFIX, name)
+
+/***************************************************************************/
+
+/* Values that can be returned from plpa_api_probe() */
+typedef enum {
+ /* Sentinel value */
+ PLPA_PROBE_UNSET,
+ /* sched_setaffinity syscall available */
+ PLPA_PROBE_OK,
+ /* syscall unavailable/unimplemented */
+ PLPA_PROBE_NOT_SUPPORTED,
+ /* we experienced some strange failure that the user should report */
+ PLPA_PROBE_UNKNOWN
+} PLPA_NAME(api_type_t);
+
+/* PLPA bitmask type */
+typedef unsigned long int PLPA_NAME(bitmask_t);
+#define PLPA_BITMASK_T_NUM_BITS (sizeof(PLPA_NAME(bitmask_t)) * 8)
+#define PLPA_BITMASK_CPU_MAX 1024
+#define PLPA_BITMASK_NUM_ELEMENTS (PLPA_BITMASK_CPU_MAX / PLPA_BITMASK_T_NUM_BITS)
+typedef struct { PLPA_NAME(bitmask_t) bitmask[PLPA_BITMASK_NUM_ELEMENTS]; } PLPA_NAME(cpu_set_t);
+
+/***************************************************************************/
+
+/* Internal macro for identifying the byte in a bitmask array */
+#define PLPA_CPU_BYTE(num) (num / PLPA_BITMASK_T_NUM_BITS)
+
+/* Internal macro for identifying the bit in a bitmask array */
+#define PLPA_CPU_BIT(num) (num % PLPA_BITMASK_T_NUM_BITS)
+
+/***************************************************************************/
+
+/* Public macro to zero out a PLPA cpu set */
+#define PLPA_CPU_ZERO(cpuset) \
+ memset(cpuset, 0, sizeof(PLPA_NAME(cpu_set_t)))
+
+/* Public macro to set a bit in a PLPA cpu set */
+#define PLPA_CPU_SET(num, cpuset) \
+ (cpuset)->bitmask[PLPA_CPU_BYTE(num)] |= (1 << PLPA_CPU_BIT(num))
+
+/* Public macro to clear a bit in a PLPA cpu set */
+#define PLPA_CPU_CLR(num, cpuset) \
+ (cpuset)->bitmask[PLPA_CPU_BYTE(num)] &= ~(1 << PLPA_CPU_BIT(num))
+
+/* Public macro to test if a bit is set in a PLPA cpu set */
+#define PLPA_CPU_ISSET(num, cpuset) \
+ (0 != ((cpuset)->bitmask[PLPA_CPU_BYTE(num)] & (1 << PLPA_CPU_BIT(num))))
+
+/***************************************************************************/
+
+/* Check what API is on this machine */
+PLPA_NAME(api_type_t) PLPA_NAME(api_probe)(void);
+
+/* Set processor affinity */
+int PLPA_NAME(sched_setaffinity)(pid_t pid, size_t cpusetsize,
+ const PLPA_NAME(cpu_set_t) *cpuset);
+
+/* Get processor affinity */
+int PLPA_NAME(sched_getaffinity)(pid_t pid, size_t cpusetsize,
+ PLPA_NAME(cpu_set_t) *cpuset);
+
+#endif /* PLPA_BOTTOM_H */
+
Added: mlton/branches/shared-heap-multicore/runtime/plpa/plpa_dispatch.c
===================================================================
--- mlton/branches/shared-heap-multicore/runtime/plpa/plpa_dispatch.c 2008-03-03 14:42:04 UTC (rev 6431)
+++ mlton/branches/shared-heap-multicore/runtime/plpa/plpa_dispatch.c 2008-03-03 14:52:04 UTC (rev 6432)
@@ -0,0 +1,171 @@
+/* -*- c -*-
+ *
+ * Copyright (c) 2004-2006 The Trustees of Indiana University.
+ * All rights reserved.
+ * Copyright (c) 2004-2005 The Regents of the University of California.
+ * All rights reserved.
+ * $COPYRIGHT$
+ *
+ * Additional copyrights may follow
+ *
+ * $HEADER$
+ */
+
+#include <errno.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+#include <plpa.h>
+#include <plpa_internal.h>
+
+/*
+ * Call the kernel's setaffinity, massaging the user's input
+ * parameters as necessary
+ */
+int PLPA_NAME(sched_setaffinity)(pid_t pid, size_t cpusetsize,
+ const PLPA_NAME(cpu_set_t) *cpuset)
+{
+ int ret;
+ size_t i;
+ PLPA_NAME(cpu_set_t) tmp;
+
+ switch (PLPA_NAME(api_probe)()) {
+ case PLPA_PROBE_OK:
+ /* This shouldn't happen, but check anyway */
+ if (cpusetsize > sizeof(*cpuset)) {
+ return EINVAL;
+ }
+ if (NULL == cpuset) {
+ return EINVAL;
+ }
+
+ /* If the user-supplied bitmask is smaller than what the
+ kernel wants, zero out a temporary buffer of the size that
+ the kernel wants and copy the user-supplied bitmask to the
+ lower part of the temporary buffer. This could be done
+ more efficiently, but we're looking for clarity/simplicity
+ of code here -- this is not intended to be
+ performance-critical. */
+ if (cpusetsize < PLPA_NAME(len)) {
+ memset(&tmp, 0, sizeof(tmp));
+ for (i = 0; i < cpusetsize * 8; ++i) {
+ if (PLPA_CPU_ISSET(i, cpuset)) {
+ PLPA_CPU_SET(i, &tmp);
+ }
+ }
+ }
+
+ /* If the user-supplied bitmask is larger than what the kernel
+ will accept, scan it and see if there are any set bits in
+ the part larger than what the kernel will accept. If so,
+ return EINVAL. Otherwise, copy the part that the kernel
+ will accept into a temporary and use that. Again,
+ efficinency is not the issue of this code -- clarity is. */
+ else if (cpusetsize > PLPA_NAME(len)) {
+ for (i = PLPA_NAME(len) * 8; i < cpusetsize * 8; ++i) {
+ if (PLPA_CPU_ISSET(i, cpuset)) {
+ return EINVAL;
+ }
+ }
+ /* No upper-level bits are set, so now copy over the bits
+ that the kernel will look at */
+ memset(&tmp, 0, sizeof(tmp));
+ for (i = 0; i < PLPA_NAME(len) * 8; ++i) {
+ if (PLPA_CPU_ISSET(i, cpuset)) {
+ PLPA_CPU_SET(i, &tmp);
+ }
+ }
+ }
+
+ /* Otherwise, the user supplied a buffer that is exactly the
+ right size. Just for clarity of code, copy the user's
+ buffer into the temporary and use that. */
+ else {
+ memcpy(&tmp, cpuset, cpusetsize);
+ }
+
+ /* Now do the syscall */
+ ret = syscall(__NR_sched_setaffinity, 0, PLPA_NAME(len), &tmp);
+
+ /* Return 0 upon success. According to
+ http://www.open-mpi.org/community/lists/plpa-users/2006/02/0016.php,
+ all the kernel implementations return >= 0 upon success. */
+ if (ret >= 0) {
+ return 0;
+ } else {
+ return ret;
+ }
+ break;
+
+ case PLPA_PROBE_NOT_SUPPORTED:
+ /* Process affinity not supported here */
+ return ENOSYS;
+ break;
+
+ default:
+ /* Something went wrong */
+ /* JMS: would be good to have something other than EINVAL here
+ -- suggestions? */
+ return EINVAL;
+ break;
+ }
+}
+
+
+/*
+ * Call the kernel's getaffinity, massaging the user's input
+ * parameters as necessary
+ */
+int PLPA_NAME(sched_getaffinity)(pid_t pid, size_t cpusetsize,
+ PLPA_NAME(cpu_set_t) *cpuset)
+{
+ int ret;
+
+ switch (PLPA_NAME(api_probe)()) {
+ case PLPA_PROBE_OK:
+ /* This shouldn't happen, but check anyway */
+ if (PLPA_NAME(len) > sizeof(*cpuset)) {
+ return EINVAL;
+ }
+ if (NULL == cpuset) {
+ return EINVAL;
+ }
+
+ /* If the user supplied a buffer that is too small, then don't
+ even bother */
+ if (cpusetsize < PLPA_NAME(len)) {
+ return EINVAL;
+ }
+
+ /* Now we know that the user's buffer is >= the size required
+ by the kernel. If it's >, then zero it out so that the
+ bits at the top are cleared (since they won't be set by the
+ kernel) */
+ if (cpusetsize > PLPA_NAME(len)) {
+ memset(cpuset, 0, sizeof(*cpuset));
+ }
+
+ /* Now do the syscall */
+ ret = syscall(__NR_sched_getaffinity, 0, PLPA_NAME(len), cpuset);
+
+ /* Return 0 upon success. According to
+ http://www.open-mpi.org/community/lists/plpa-users/2006/02/0016.php,
+ all the kernel implementations return >= 0 upon success. */
+ if (ret >= 0) {
+ return 0;
+ } else {
+ return ret;
+ }
+ break;
+
+ case PLPA_PROBE_NOT_SUPPORTED:
+ /* Process affinity not supported here */
+ return ENOSYS;
+ break;
+
+ default:
+ /* Something went wrong */
+ return EINVAL;
+ break;
+ }
+}
+
Added: mlton/branches/shared-heap-multicore/runtime/plpa/plpa_internal.h
===================================================================
--- mlton/branches/shared-heap-multicore/runtime/plpa/plpa_internal.h 2008-03-03 14:42:04 UTC (rev 6431)
+++ mlton/branches/shared-heap-multicore/runtime/plpa/plpa_internal.h 2008-03-03 14:52:04 UTC (rev 6432)
@@ -0,0 +1,23 @@
+/* -*- c -*-
+ *
+ * Copyright (c) 2004-2005 The Trustees of Indiana University.
+ * All rights reserved.
+ * Copyright (c) 2004-2005 The Regents of the University of California.
+ * All rights reserved.
+ * $COPYRIGHT$
+ *
+ * Additional copyrights may follow
+ *
+ * $HEADER$
+ */
+
+#ifndef PLPA_INTERNAL_H
+#define PLPA_INTERNAL_H
+
+#include <plpa.h>
+
+/* Cached size of the affinity buffers that the kernel expects */
+extern size_t PLPA_NAME(len);
+
+#endif /* PLPA_INTERNAL_H */
+
More information about the MLton-commit
mailing list