ADD_TEST(scala-masterslave ${TESH_COMMAND} ${TESH_OPTION} --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/scala --setenv classpath=${TESH_CLASSPATH} --cd ${CMAKE_BINARY_DIR}/examples/scala ${CMAKE_HOME_DIRECTORY}/examples/scala/masterslave/masterslave.tesh)
endif()
+ ADD_TEST(stack-overflow-thread ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:thread --setenv srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite --cd ${CMAKE_BINARY_DIR}/teshsuite ${CMAKE_HOME_DIRECTORY}/teshsuite/simix/stack_overflow.tesh)
+ if(CONTEXT_UCONTEXT)
+ ADD_TEST(stack-overflow-ucontext ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:ucontext --setenv srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite --cd ${CMAKE_BINARY_DIR}/teshsuite ${CMAKE_HOME_DIRECTORY}/teshsuite/simix/stack_overflow.tesh)
+ endif()
+ if(HAVE_RAWCTX)
+ ADD_TEST(stack-overflow-raw ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:raw --setenv srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite --cd ${CMAKE_BINARY_DIR}/teshsuite ${CMAKE_HOME_DIRECTORY}/teshsuite/simix/stack_overflow.tesh)
+ endif()
+
# examples/msg/mc
if(HAVE_MC)
if(CONTEXT_UCONTEXT)
double precision p, t, e
call MPI_Init(ierr)
+ if (ierr .ne. MPI_SUCCESS) then
+ print *, 'MPI_Init failed:', ierr
+ stop 1
+ endif
call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr)
+ if (ierr .ne. MPI_SUCCESS) then
+ print *, 'MPI_Comm_rank failed:', ierr
+ call MPI_Abort(MPI_COMM_WORLD, 1, ierr)
+ stop 1
+ endif
pstates = smpi_get_host_nb_pstates()
end do
call MPI_Finalize(ierr)
+ if (ierr .ne. MPI_SUCCESS) then
+ print *, 'MPI_Finalize failed:', ierr
+ call MPI_Abort(MPI_COMM_WORLD, 1, ierr)
+ stop 1
+ endif
end program main
double precision p, t, e
call MPI_Init(ierr)
+ if (ierr .ne. MPI_SUCCESS) then
+ print *, 'MPI_Init failed:', ierr
+ stop 1
+ endif
call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr)
+ if (ierr .ne. MPI_SUCCESS) then
+ print *, 'MPI_Comm_rank failed:', ierr
+ call MPI_Abort(MPI_COMM_WORLD, 1, ierr)
+ stop 1
+ endif
pstates = smpi_get_host_nb_pstates()
end do
call MPI_Finalize(ierr)
+ if (ierr .ne. MPI_SUCCESS) then
+ print *, 'MPI_Finalize failed:', ierr
+ call MPI_Abort(MPI_COMM_WORLD, 1, ierr)
+ stop 1
+ endif
end program main
char buf[1024];
char *s;
size_t sz, x;
+ int err;
- if (MPI_Init(&argc, &argv) != MPI_SUCCESS) {
- fprintf(stderr, "MPI initialization failed!\n");
+ err = MPI_Init(&argc, &argv);
+ if (err != MPI_SUCCESS) {
+ fprintf(stderr, "MPI_init failed: %d\n", err);
exit(EXIT_FAILURE);
}
- MPI_Comm_rank(MPI_COMM_WORLD, &rank); /* Get id of this process */
+ err = MPI_Comm_rank(MPI_COMM_WORLD, &rank); /* Get id of this process */
+ if (err != MPI_SUCCESS) {
+ fprintf(stderr, "MPI_Comm_rank failed: %d", err);
+ MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE);
+ exit(EXIT_FAILURE);
+ }
pstates = smpi_get_host_nb_pstates();
MPI_Wtime(), rank, smpi_get_host_consumed_energy());
}
- return MPI_Finalize();
+ err = MPI_Finalize();
+ if (err != MPI_SUCCESS) {
+ fprintf(stderr, "MPI_Finalize failed: %d\n", err);
+ MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE);
+ exit(EXIT_FAILURE);
+ }
+
+ return EXIT_SUCCESS;
}
extern char* smx_context_factory_name;
extern int smx_context_stack_size;
extern int smx_context_stack_size_was_set;
+extern int smx_context_guard_size;
+extern int smx_context_guard_size_was_set;
/* *********************** */
/* Context type definition */
SG_BEGIN_DECL()
+/** Cache the size of a memory page for the current system. */
+XBT_PUBLIC_DATA(int) xbt_pagesize;
+
XBT_PUBLIC(const char *) xbt_procname(void);
#define XBT_BACKTRACE_SIZE 10 /* FIXME: better place? Do document */
XBT_PUBLIC(void) xbt_os_thread_cancel(xbt_os_thread_t thread);
XBT_PUBLIC(void *) xbt_os_thread_getparam(void);
XBT_PUBLIC(void) xbt_os_thread_setstacksize(int stack_size);
+XBT_PUBLIC(void) xbt_os_thread_setguardsize(int guard_size);
/** \brief Thread mutex data type (opaque structure) */
typedef struct xbt_os_mutex_ *xbt_os_mutex_t;
raw_heap = NULL;
#else
/* Create the second region a page after the first one ends + safety gap */
- raw_heap = xbt_mheap_new(-1, (char*)(std_heap) + STD_HEAP_SIZE + getpagesize());
+ raw_heap = xbt_mheap_new(-1, (char*)(std_heap) + STD_HEAP_SIZE + xbt_pagesize);
xbt_assert(raw_heap != NULL);
#endif
}
smx_context_stack_size = xbt_cfg_get_int(_sg_cfg_set, name) * 1024;
}
+static void _sg_cfg_cb_context_guard_size(const char *name, int pos)
+{
+ smx_context_guard_size_was_set = 1;
+ smx_context_guard_size = xbt_cfg_get_int(_sg_cfg_set, name) * xbt_pagesize;
+}
+
static void _sg_cfg_cb_contexts_nthreads(const char *name, int pos)
{
SIMIX_context_set_nthreads(xbt_cfg_get_int(_sg_cfg_set, name));
/* No, it was not set yet (the above setdefault() changed this to 1). */
smx_context_stack_size_was_set = 0;
+ /* guard size for contexts stacks in memory pages */
+ xbt_cfg_register(&_sg_cfg_set, "contexts/guard_size",
+ "Guard size for contexts stacks in memory pages",
+ xbt_cfgelm_int, 1, 1, _sg_cfg_cb_context_guard_size, NULL);
+ xbt_cfg_setdefault_int(_sg_cfg_set, "contexts/guard_size", 1);
+ /* No, it was not set yet (the above setdefault() changed this to 1). */
+ smx_context_guard_size_was_set = 0;
+
/* number of parallel threads for user processes */
xbt_cfg_register(&_sg_cfg_set, "contexts/nthreads",
"Number of parallel threads used to execute user contexts",
#include "smx_private.h"
#include "simgrid/sg_config.h"
#include "internal_config.h"
+#include "simgrid/modelchecker.h"
+#include <sys/mman.h>
#ifdef HAVE_VALGRIND_VALGRIND_H
# include <valgrind/valgrind.h>
smx_ctx_factory_initializer_t smx_factory_initializer_to_use = NULL;
int smx_context_stack_size;
int smx_context_stack_size_was_set = 0;
+int smx_context_guard_size;
+int smx_context_guard_size_was_set = 0;
#ifdef HAVE_THREAD_LOCAL_STORAGE
static __thread smx_context_t smx_current_context_parallel;
#else
void *SIMIX_context_stack_new(void)
{
- void *stack = xbt_malloc0(smx_context_stack_size);
+ void *stack;
+
+ if (smx_context_guard_size > 0 && !MC_is_active()) {
+ size_t size = smx_context_stack_size + smx_context_guard_size;
+#ifdef HAVE_MC
+ /* Cannot use posix_memalign when HAVE_MC. Align stack by hand, and save the
+ * pointer returned by xbt_malloc0. */
+ char *alloc = xbt_malloc0(size + xbt_pagesize);
+ stack = alloc - ((uintptr_t)alloc & (xbt_pagesize - 1)) + xbt_pagesize;
+ *((void **)stack - 1) = alloc;
+#else
+ if (posix_memalign(&stack, xbt_pagesize, size) != 0)
+ xbt_die("Failed to allocate stack.");
+#endif
+ if (mprotect(stack, smx_context_guard_size, PROT_NONE) == -1) {
+ XBT_WARN("Failed to protect stack: %s", strerror(errno));
+ /* That's not fatal, pursue anyway. */
+ }
+ stack = (char *)stack + smx_context_guard_size;
+ } else {
+ stack = xbt_malloc0(smx_context_stack_size);
+ }
#ifdef HAVE_VALGRIND_VALGRIND_H
unsigned int valgrind_stack_id =
VALGRIND_STACK_DEREGISTER(valgrind_stack_id);
#endif
+ if (smx_context_guard_size > 0 && !MC_is_active()) {
+ stack = (char *)stack - smx_context_guard_size;
+ if (mprotect(stack, smx_context_guard_size,
+ PROT_READ | PROT_WRITE | PROT_EXEC) == -1) {
+ XBT_WARN("Failed to remove page protection: %s", strerror(errno));
+ /* try to pursue anyway */
+ }
+#ifdef HAVE_MC
+ /* Retrieve the saved pointer. See SIMIX_context_stack_new above. */
+ stack = *((void **)stack - 1);
+#endif
+ }
xbt_free(stack);
}
context->end = xbt_os_sem_init(0);
if (smx_context_stack_size_was_set)
xbt_os_thread_setstacksize(smx_context_stack_size);
+ if (smx_context_guard_size_was_set)
+ xbt_os_thread_setguardsize(smx_context_guard_size);
/* create and start the process */
/* NOTE: The first argument to xbt_os_thread_create used to be the process *
{
smx_ctx_thread_t context = (smx_ctx_thread_t) param;
+ /* Install alternate signal stack, for SIGSEGV handler. */
+ stack_t stack;
+ stack.ss_sp = sigsegv_stack;
+ stack.ss_size = sizeof sigsegv_stack;
+ stack.ss_flags = 0;
+ sigaltstack(&stack, NULL);
+
/* Tell the maestro we are starting, and wait for its green light */
xbt_os_sem_release(context->end);
xbt_os_sem_acquire(context->begin);
exit(1);
}
+static void _XBT_CALL segvhandler(int signum, siginfo_t *siginfo, void *context)
+{
+ if (siginfo->si_signo == SIGSEGV && siginfo->si_code == SEGV_ACCERR) {
+ fprintf(stderr,
+ "Access violation detected. This can result from a stack overflow.\n"
+ "Try to increase stack size with --cfg=contexts/stack_size (current size is %d KiB).\n",
+ smx_context_stack_size / 1024);
+ if (XBT_LOG_ISENABLED(simix_kernel, xbt_log_priority_debug)) {
+ fprintf(stderr,
+ "siginfo = {si_signo = %d, si_errno = %d, si_code = %d, si_addr = %p}\n",
+ siginfo->si_signo, siginfo->si_errno, siginfo->si_code, siginfo->si_addr);
+ }
+ }
+ raise(signum);
+}
+
+char sigsegv_stack[SIGSTKSZ]; /* alternate stack for SIGSEGV handler */
+
+/**
+ * Install signal handler for SIGSEGV. Check that nobody has already installed
+ * its own handler. For example, the Java VM does this.
+ */
+static void install_segvhandler(void)
+{
+ stack_t stack, old_stack;
+ stack.ss_sp = sigsegv_stack;
+ stack.ss_size = sizeof sigsegv_stack;
+ stack.ss_flags = 0;
+
+ if (sigaltstack(&stack, &old_stack) == -1) {
+ XBT_WARN("Failed to register alternate signal stack: %s",
+ strerror(errno));
+ return;
+ }
+ if (!(old_stack.ss_flags & SS_DISABLE)) {
+ XBT_DEBUG("An alternate stack was already installed (sp=%p, size=%zd, flags=%x). Restore it.",
+ old_stack.ss_sp, old_stack.ss_size, old_stack.ss_flags);
+ sigaltstack(&old_stack, NULL);
+ }
+
+ struct sigaction action, old_action;
+ action.sa_sigaction = segvhandler;
+ action.sa_flags = SA_ONSTACK | SA_RESETHAND | SA_SIGINFO;
+ sigemptyset(&action.sa_mask);
+
+ if (sigaction(SIGSEGV, &action, &old_action) == -1) {
+ XBT_WARN("Failed to register signal handler for SIGSEGV: %s",
+ strerror(errno));
+ return;
+ }
+ if ((old_action.sa_flags & SA_SIGINFO) || old_action.sa_handler != SIG_DFL) {
+ XBT_DEBUG("A signal handler was already installed for SIGSEGV (%p). Restore it.",
+ (old_action.sa_flags & SA_SIGINFO) ?
+ (void*)old_action.sa_sigaction : (void*)old_action.sa_handler);
+ sigaction(SIGSEGV, &old_action, NULL);
+ }
+}
+
/********************************* SIMIX **************************************/
XBT_INLINE double SIMIX_timer_next(void)
/* Prepare to display some more info when dying on Ctrl-C pressing */
signal(SIGINT, inthandler);
+ /* Install SEGV handler */
+ install_segvhandler();
+
/* register a function to be called by SURF after the environment creation */
sg_platf_init();
sg_platf_postparse_add_cb(SIMIX_post_create_environment);
void SIMIX_context_mod_init(void);
void SIMIX_context_mod_exit(void);
+XBT_PUBLIC_DATA(char sigsegv_stack[SIGSTKSZ]);
+
/* We are using the bottom of the stack to save some information, like the
* valgrind_stack_id. Define smx_context_usable_stack_size to give the remaining
* size for the stack. */
heaplimit = ((struct mdesc *)heap1)->heaplimit;
- s_heap = (char *)mmalloc_get_current_heap() - STD_HEAP_SIZE - getpagesize();
+ s_heap = (char *)mmalloc_get_current_heap() - STD_HEAP_SIZE - xbt_pagesize;
heapbase1 = (char *)heap1 + BLOCKSIZE;
heapbase2 = (char *)heap2 + BLOCKSIZE;
/* Heap information */
heaplimit = ((struct mdesc *)heap1)->heaplimit;
- s_heap = (char *)mmalloc_get_current_heap() - STD_HEAP_SIZE - getpagesize();
+ s_heap = (char *)mmalloc_get_current_heap() - STD_HEAP_SIZE - xbt_pagesize;
heapbase1 = (char *)heap1 + BLOCKSIZE;
heapbase2 = (char *)heap2 + BLOCKSIZE;
{
int res;
if (__mmalloc_default_mdp == NULL) {
- unsigned long mask = ~((unsigned long)getpagesize() - 1);
+ unsigned long mask = ~((unsigned long)xbt_pagesize - 1);
void *addr = (void*)(((unsigned long)sbrk(0) + HEAP_OFFSET) & mask);
__mmalloc_default_mdp = xbt_mheap_new(-1, addr);
/* Fixme? only the default mdp in protected against forks */
#include "mmprivate.h"
-/* Cache the pagesize for the current host machine. Note that if the host
- does not readily provide a getpagesize() function, we need to emulate it
- elsewhere, not clutter up this file with lots of kluges to try to figure
- it out. */
-
-static size_t pagesize;
-
-#define PAGE_ALIGN(addr) (void*) (((long)(addr) + pagesize - 1) & \
- ~(pagesize - 1))
+#define PAGE_ALIGN(addr) (void*) (((long)(addr) + xbt_pagesize - 1) & \
+ ~((long)xbt_pagesize - 1))
/* Return MAP_PRIVATE if MDP represents /dev/zero. Otherwise, return
MAP_SHARED. */
char buf = 0; /* Single byte to write to extend mapped file */
// fprintf(stderr,"increase %p by %u\n",mdp,size);
- if (pagesize == 0)
- pagesize = getpagesize();
if (size == 0) {
/* Just return the current "break" value. */
#include "xbt/misc.h"
#include "simgrid_config.h" /* _XBT_WIN32 */
#include "internal_config.h" /* MMALLOC_WANT_OVERRIDE_LEGACY */
-
+#include "portable.h"
#include "xbt/sysdep.h"
#include "xbt/log.h"
#include "xbt/dynar.h"
int xbt_initialized = 0;
int _sg_do_clean_atexit = 1;
+int xbt_pagesize;
+
/* Declare xbt_preinit and xbt_postexit as constructor/destructor of the library.
* This is crude and rather compiler-specific, unfortunately.
*/
static void xbt_preinit(void) {
unsigned int seed = 2147483647;
+ xbt_pagesize = sysconf(_SC_PAGESIZE);
+
#ifdef MMALLOC_WANT_OVERRIDE_LEGACY
mmalloc_preinit();
#endif
static pthread_key_t xbt_self_thread_key;
static int thread_mod_inited = 0;
-/* attribute structure to handle pthread stack size changing */
+/* defaults attribute for pthreads */
//FIXME: find where to put this
-static pthread_attr_t attr;
-static int thread_attr_inited = 0;
+static pthread_attr_t thread_attr;
/* frees the xbt_os_thread_t corresponding to the current thread */
static void xbt_os_thread_free_thread_data(xbt_os_thread_t thread)
if ((errcode = pthread_setspecific(xbt_self_thread_key, main_thread)))
THROWF(system_error, errcode,
"pthread_setspecific failed for xbt_self_thread_key");
-
__xbt_running_ctx_fetch = _os_thread_get_running_ctx;
__xbt_ex_terminate = _os_thread_ex_terminate;
+ pthread_attr_init(&thread_attr);
+
thread_mod_inited = 1;
#ifndef HAVE_SEM_INIT
XBT_RUNNING_CTX_INITIALIZE(res_thread->running_ctx);
res_thread->extra_data = extra_data;
- if ((errcode = pthread_create(&(res_thread->t), thread_attr_inited!=0? &attr: NULL,
+ if ((errcode = pthread_create(&(res_thread->t), &thread_attr,
wrapper_start_routine, res_thread)))
THROWF(system_error, errcode,
"pthread_create failed: %s", strerror(errcode));
void xbt_os_thread_setstacksize(int stack_size)
{
+ size_t alignment[] = {
+ xbt_pagesize,
+#ifdef PTHREAD_STACK_MIN
+ PTHREAD_STACK_MIN,
+#endif
+ 0
+ };
size_t sz;
int res;
+ int i;
if (stack_size < 0)
xbt_die("stack size %d is negative, maybe it exceeds MAX_INT?", stack_size);
sz = stack_size;
- pthread_attr_init(&attr);
- res = pthread_attr_setstacksize(&attr, sz);
+ res = pthread_attr_setstacksize(&thread_attr, sz);
-#ifdef PTHREAD_STACK_MIN
- if (res == EINVAL) {
- /* Invalid size, try again with a multiple of PTHREAD_STACK_MIN. */
- size_t rem = sz % PTHREAD_STACK_MIN;
+ for (i = 0; res == EINVAL && alignment[i] > 0; i++) {
+ /* Invalid size, try again with next multiple of alignment[i]. */
+ size_t rem = sz % alignment[i];
if (rem != 0 || sz == 0) {
- size_t sz2 = sz - rem + PTHREAD_STACK_MIN;
- XBT_DEBUG("pthread_attr_setstacksize failed for %#zx, try again with %#zx",
+ size_t sz2 = sz - rem + alignment[i];
+ XBT_DEBUG("pthread_attr_setstacksize failed for %zd, try again with %zd",
sz, sz2);
sz = sz2;
- res = pthread_attr_setstacksize(&attr, sz);
+ res = pthread_attr_setstacksize(&thread_attr, sz);
}
}
-#endif
if (res == EINVAL)
- XBT_WARN("invalid stack size (maybe too big): %#zx", sz);
+ XBT_WARN("invalid stack size (maybe too big): %zd", sz);
else if (res != 0)
- XBT_WARN("unknown error %d in pthread stacksize setting: %#zx", res, sz);
- thread_attr_inited = 1;
+ XBT_WARN("unknown error %d in pthread stacksize setting: %zd", res, sz);
+}
+
+void xbt_os_thread_setguardsize(int guard_size)
+{
+ size_t sz = guard_size;
+ int res = pthread_attr_setguardsize(&thread_attr, sz);
+ if (res)
+ XBT_WARN("pthread_attr_setguardsize failed (%d) for size: %zd", res, sz);
}
const char *xbt_os_thread_name(xbt_os_thread_t t)
stack_size = size;
}
+void xbt_os_thread_setguardsize(int size)
+{
+ XBT_WARN("xbt_os_thread_setguardsize is not implemented (%d)", size);
+}
+
const char *xbt_os_thread_name(xbt_os_thread_t t)
{
return t->name;
add_executable(check_defaults check_defaults.c)
target_link_libraries(check_defaults simgrid)
+add_executable(stack_overflow stack_overflow.c)
+target_link_libraries(stack_overflow simgrid)
+
set(tesh_files
${tesh_files}
${CMAKE_CURRENT_SOURCE_DIR}/factory_raw.tesh
${CMAKE_CURRENT_SOURCE_DIR}/factory_thread.tesh
${CMAKE_CURRENT_SOURCE_DIR}/factory_ucontext.tesh
+ ${CMAKE_CURRENT_SOURCE_DIR}/stack_overflow.tesh
PARENT_SCOPE
)
set(xml_files
${xml_files}
+ ${CMAKE_CURRENT_SOURCE_DIR}/stack_overflow.xml
PARENT_SCOPE
)
set(teshsuite_src
${teshsuite_src}
${CMAKE_CURRENT_SOURCE_DIR}/check_defaults.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/stack_overflow.c
PARENT_SCOPE
)
set(bin_files
--- /dev/null
+/* stack_overflow -- simple program generating a stack overflow */
+
+/* Copyright (c) 2014. The SimGrid Team.
+ * All rights reserved. */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#include "simgrid/platf.h"
+#include "simgrid/simix.h"
+#include "surf/surfxml_parse.h"
+#include "xbt/log.h"
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(test, "my log messages");
+
+static unsigned collatz(unsigned c0, unsigned n)
+{
+ unsigned x;
+ if (n == 0) {
+ x = c0;
+ } else {
+ x = collatz(c0, n - 1);
+ if (x % 2 == 0)
+ x = x / 2;
+ else
+ x = 3 * x + 1;
+ }
+ return x;
+}
+
+static int master(int argc, char *argv[])
+{
+ XBT_INFO("Launching our nice bugged recursive function...");
+ unsigned i = 1;
+ do {
+ i *= 2;
+ unsigned res = collatz(i, i);
+ XBT_VERB("collatz(%u, %u) returned %u", i, i, res);
+ } while (i <= 0x80000000u);
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ SIMIX_global_init(&argc, argv);
+
+ if (argc != 2) {
+ printf("Usage: %s platform_and_deployment.xml\n", argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ SIMIX_function_register("master", master);
+ SIMIX_create_environment(argv[1]);
+ SIMIX_launch_application(argv[1]);
+ SIMIX_run();
+
+ return 0;
+}
--- /dev/null
+! expect signal SIGSEGV
+$ ./simix/stack_overflow --cfg=contexts/stack_size:96 ${srcdir:=.}/simix/stack_overflow.xml
+> [Tremblay:master:(0) 0.000000] [test/INFO] Launching our nice bugged recursive function...
+> Access violation detected. This can result from a stack overflow.
+> Try to increase stack size with --cfg=contexts/stack_size (current size is 96 KiB).
--- /dev/null
+<?xml version='1.0'?>
+<!DOCTYPE platform SYSTEM "http://simgrid.gforge.inria.fr/simgrid.dtd">
+<platform version="3">
+
+ <!-- The hosts -->
+ <AS id="AS0" routing="Full">
+ <host id="Tremblay" power="98.095Mf"/>
+ </AS>
+
+ <!-- The master process (with some arguments) -->
+ <process host="Tremblay" function="master">
+ </process>
+
+</platform>
call mpi_comm_rank( MPI_COMM_WORLD, rank, ierr )
if (size .lt. 2) then
print *, "Must have at least 2 processes"
- call MPI_Abort( 1, MPI_COMM_WORLD, ierr )
+ call MPI_Abort( MPI_COMM_WORLD, 1, ierr )
stop
endif
call mpi_comm_size(MPI_COMM_WORLD, size, ierr )
if (size .lt. 2) then
print *, "Must have at least 2 processes"
- call MPI_Abort( 1, MPI_COMM_WORLD, ierr )
+ call MPI_Abort( MPI_COMM_WORLD, 1, ierr )
stop
endif
xbt_init(&argc,argv);
XBT_INFO("Allocating a new heap");
- unsigned long mask = ~((unsigned long)getpagesize() - 1);
+ unsigned long mask = ~((unsigned long)xbt_pagesize - 1);
void *addr = (void*)(((unsigned long)sbrk(0) + BUFFSIZE) & mask);
heapA = xbt_mheap_new(-1, addr);
if (heapA == NULL) {