/** Constructor, taking the command line parameters of your main function */
Engine(int *argc, char **argv);
+ /** Finalize the default engine and all its dependencies */
+ static void shutdown();
+
/** @brief Load a platform file describing the environment
*
* The environment is either a XML file following the simgrid.dtd formalism, or a lua file.
/** Returns whether the mailbox contains queued communications */
bool empty();
+ /** Declare that the specified process is a permanent receiver on that mailbox
+ *
+ * It means that the communications sent to this mailbox will start flowing to its host even before he does a recv().
+ * This models the real behavior of TCP and MPI communications, amongst other.
+ */
+ void setReceiver(smx_process_t process);
+ /** Return the process declared as permanent receiver, or nullptr if none **/
+ smx_process_t receiver();
+
private:
std::string name_;
smx_mailbox_t inferior_;
static boost::unordered_map<std::string, Mailbox *> *mailboxes;
+ friend s4u::Engine;
};
}} // namespace simgrid::s4u
XBT_PUBLIC(sg_mbox_t) sg_mbox_by_name(const char*name);
XBT_PUBLIC(int) sg_mbox_is_empty(sg_mbox_t mbox);
+XBT_PUBLIC(void)sg_mbox_setReceiver(sg_mbox_t mbox, smx_process_t process);
+XBT_PUBLIC(smx_process_t) sg_mbox_receiver(sg_mbox_t mbox);
#endif /* SIMGRID_S4U_MAILBOX_HPP */
protected:
smx_storage_t inferior();
private:
+ friend s4u::Engine;
+
static boost::unordered_map<std::string, Storage *> *storages_;
std::string name_;
smx_storage_t inferior_;
#include "mc/mc.h"
#include "simgrid/s4u/As.hpp"
#include "simgrid/s4u/engine.hpp"
+#include "simgrid/s4u/mailbox.hpp"
+#include "simgrid/s4u/storage.hpp"
XBT_LOG_NEW_CATEGORY(s4u,"Log channels of the S4U (Simgrid for you) interface");
using namespace simgrid;
return s4u::Engine::instance_;
}
+void s4u::Engine::shutdown() {
+ delete s4u::Engine::instance_;
+ s4u::Engine::instance_ = nullptr;
+ delete s4u::Mailbox::mailboxes;
+ delete s4u::Storage::storages_;
+}
+
double s4u::Engine::getClock()
{
return SIMIX_get_clock();
return nullptr == simcall_mbox_get_head(inferior_);
}
+void s4u::Mailbox::setReceiver(smx_process_t process) {
+ simcall_mbox_set_receiver(inferior_, process);
+}
+smx_process_t s4u::Mailbox::receiver() {
+ return simcall_mbox_get_receiver(inferior_);
+}
+
+/*------- C functions -------*/
+
sg_mbox_t sg_mbox_by_name(const char*name){
return s4u::Mailbox::byName(name);
}
int sg_mbox_is_empty(sg_mbox_t mbox) {
return mbox->empty();
}
+void sg_mbox_setReceiver(sg_mbox_t mbox, smx_process_t process) {
+ mbox->setReceiver(process);
+}
+smx_process_t sg_mbox_receiver(sg_mbox_t mbox) {
+ return mbox->receiver();
+}
rawctx_entry_point_t entry_point, void* arg);
extern "C" void raw_swapcontext(raw_stack_t* old, raw_stack_t new_context);
+// TODO, we should handle FP, MMX and the x87 control-word (for x86 and x86_64)
+
#if SIMGRID_PROCESSOR_x86_64
__asm__ (
#if defined(__APPLE__)
".type raw_swapcontext,@function\n"
"raw_swapcontext:\n"
#endif
- " movl 4(%esp),%eax\n" /* old */
- " movl 8(%esp),%edx\n" /* new */
+ // Fetch the parameters:
+ " movl 4(%esp),%eax\n" /* old (raw_stack_t*) */
+ " movl 8(%esp),%edx\n" /* new (raw_stack_t) */
+ // Save registers of the current context on the stack:
" pushl %ebp\n"
" pushl %ebx\n"
" pushl %esi\n"
" pushl %edi\n"
+ // Save the current context (stack pointer) in *old:
" movl %esp,(%eax)\n"
+ // Switch to the stack of the new context:
" movl %edx,%esp\n"
+ // Pop the values of the new context:
" popl %edi\n"
" popl %esi\n"
" popl %ebx\n"
" popl %ebp\n"
+ // Return using the return address of the new context:
" retl\n"
);
#else
typedef struct s_smx_mailbox {
char *name;
std::deque<smx_synchro_t> *comm_queue;
- void *data;
smx_process_t permanent_receiver; //process which the mailbox is attached to
std::deque<smx_synchro_t> *done_comm_queue;//messages already received in the permanent receive mode
} s_smx_mailbox_t;
if(req->flags & RECV)
subtype->unserialize(req->buf, req->old_buf, req->real_size/smpi_datatype_size(datatype) ,
datatype->substruct, req->op);
- if(req->detached == 0) free(req->buf);
+ xbt_free(req->buf);
}else if(req->flags & RECV){//apply op on contiguous buffer for accumulate
int n =req->real_size/smpi_datatype_size(datatype);
smpi_op_apply(req->op, req->buf, req->old_buf, &n, &datatype);
MPI_COMM_WORLD = MPI_COMM_NULL;
+ if (!MC_is_active()) {
+ xbt_os_timer_free(global_timer);
+ }
+
xbt_free(index_to_process_data);
if(smpi_privatize_global_variables)
smpi_destroy_global_memory_segments();
win->requests=xbt_dynar_new(sizeof(MPI_Request), NULL);
smpi_mpi_waitall(size,treqs,MPI_STATUSES_IGNORE);
xbt_free(treqs);
+ smpi_group_unuse(win->group);
win->opened--; //we're closed for business !
return MPI_SUCCESS;
}
win->requests=xbt_dynar_new(sizeof(MPI_Request), NULL);
smpi_mpi_waitall(size,treqs,MPI_STATUSES_IGNORE);
xbt_free(treqs);
+ smpi_group_unuse(win->group);
win->opened--; //we're opened for business !
return MPI_SUCCESS;
}
if (host->properties() != NULL) {
char* off_power_str = (char*)xbt_dict_get_or_null(host->properties(), "watt_off");
- if (off_power_str != NULL)
- watts_off = xbt_str_parse_double(off_power_str,
- bprintf("Invalid value for property watt_off of host %s: %%s",host->name().c_str()));
+ if (off_power_str != NULL) {
+ char *msg = bprintf("Invalid value for property watt_off of host %s: %%s",host->name().c_str());
+ watts_off = xbt_str_parse_double(off_power_str, msg);
+ xbt_free(msg);
+ }
else
watts_off = 0;
}
/* min_power corresponds to the idle power (cpu load = 0) */
/* max_power is the power consumed at 100% cpu load */
+ char *msg_min = bprintf("Invalid min value for pstate %d on host %s: %%s", i, host->name().c_str());
+ char *msg_max = bprintf("Invalid min value for pstate %d on host %s: %%s", i, host->name().c_str());
power_range_watts_list.push_back(power_range(
- xbt_str_parse_double(xbt_dynar_get_as(current_power_values, 0, char*),
- bprintf("Invalid min value for pstate %d on host %s: %%s", i, host->name().c_str())),
- xbt_str_parse_double(xbt_dynar_get_as(current_power_values, 1, char*),
- bprintf("Invalid min value for pstate %d on host %s: %%s", i, host->name().c_str()))
+ xbt_str_parse_double(xbt_dynar_get_as(current_power_values, 0, char*), msg_min),
+ xbt_str_parse_double(xbt_dynar_get_as(current_power_values, 1, char*), msg_max)
));
+ xbt_free(msg_min);
+ xbt_free(msg_max);
xbt_dynar_free(¤t_power_values);
}
#include "mc/mc.h"
#include "virtual_machine.hpp"
#include "src/instr/instr_private.h" // TRACE_is_enabled(). FIXME: remove by subscribing tracing to the surf signals
+#include "simgrid/s4u/engine.hpp"
XBT_LOG_NEW_CATEGORY(surf, "All SURF categories");
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_kernel, surf, "Logging specific to SURF (kernel)");
tmgr_finalize();
sg_platf_exit();
+ simgrid::s4u::Engine::shutdown();
NOW = 0; /* Just in case the user plans to restart the simulation afterward */
}
XBT_VERB("Create VM(%s)@PM(%s) with %ld mounted disks", name, hostPM_->name().c_str(), xbt_dynar_length(p_storage));
}
+VMHL13::~VMHL13() {
+ delete p_cpu;
+}
void VMHL13::suspend()
{
class VMHL13 : public VirtualMachine {
public:
VMHL13(VMModel *model, const char* name, sg_host_t host_PM);
- ~VMHL13() {}
+ ~VMHL13();
void suspend() override;
void resume() override;
}
MPI_Finalize();
-
+ free(sbuf);
+ free(rbuf);
return 0;
}
MPI_Win_fence(0, win);
}
MPI_Win_free(&win);
+ free(A);
}
MPI_Comm_free(&CommDeuce);
MTest_Finalize(errs);
ENDIF()
IF(enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN AND HAVE_THREAD_CONTEXTS)
- ADD_TEST(test-smpi-mpich3-thread-f77 ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/f77/ ${PERL_EXECUTABLE} ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests ${TESH_OPTION} -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/f77/ -tests=testlist -execarg=--cfg=contexts/stack_size:8000 -execarg=--cfg=smpi/privatize-global-variables:${HAVE_PRIVATIZATION})
+ ADD_TEST(test-smpi-mpich3-thread-f77 ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/f77/ ${PERL_EXECUTABLE} ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests ${TESH_OPTION} -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/f77/ -tests=testlist -execarg=--cfg=contexts/stack_size:8000 -execarg=--cfg=contexts/factory:thread -execarg=--cfg=smpi/privatize-global-variables:${HAVE_PRIVATIZATION})
SET_TESTS_PROPERTIES(test-smpi-mpich3-thread-f77 PROPERTIES PASS_REGULAR_EXPRESSION "tests passed!")
- ADD_TEST(test-smpi-mpich3-thread-f90 ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/f90/ ${PERL_EXECUTABLE} ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests ${TESH_OPTION} -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/f90/ -tests=testlist -execarg=--cfg=smpi/privatize-global-variables:${HAVE_PRIVATIZATION})
+ ADD_TEST(test-smpi-mpich3-thread-f90 ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/f90/ ${PERL_EXECUTABLE} ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests ${TESH_OPTION} -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/f90/ -tests=testlist -execarg=--cfg=smpi/privatize-global-variables:${HAVE_PRIVATIZATION} -execarg=--cfg=contexts/factory:thread)
SET_TESTS_PROPERTIES(test-smpi-mpich3-thread-f90 PROPERTIES PASS_REGULAR_EXPRESSION "tests passed!")
ENDIF()