Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
kill two more useless calls
[simgrid.git] / src / simix / Context.cpp
1 /* Copyright (c) 2007-2010, 2012-2015. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 #include <cstdint>
8
9 #include <memory>
10 #include <functional>
11 #include <utility>
12
13 #include <simgrid/simix.hpp>
14
15 #include "mc/mc.h"
16
17 #include <src/simix/smx_private.h>
18
19 void SIMIX_process_set_cleanup_function(
20   smx_process_t process, void_pfn_smxprocess_t cleanup)
21 {
22   process->context->set_cleanup(cleanup);
23 }
24
25 namespace simgrid {
26 namespace simix {
27
28 class XBT_PRIVATE args {
29 private:
30   int argc_;
31   char** argv_;
32 public:
33
34   // Main constructors
35   args() : argc_(0), argv_(nullptr) {}
36   args(int argc, char** argv) : argc_(argc), argv_(argv) {}
37
38   // Free
39   void clear()
40   {
41     for (int i = 0; i < this->argc_; i++)
42       free(this->argv_[i]);
43     free(this->argv_);
44     this->argc_ = 0;
45     this->argv_ = nullptr;
46   }
47   ~args() { clear(); }
48
49   // Copy
50   args(args const& that) = delete;
51   args& operator=(args const& that) = delete;
52
53   // Move:
54   args(args&& that) : argc_(that.argc_), argv_(that.argv_)
55   {
56     that.argc_ = 0;
57     that.argv_ = nullptr;
58   }
59   args& operator=(args&& that)
60   {
61     this->argc_ = that.argc_;
62     this->argv_ = that.argv_;
63     that.argc_ = 0;
64     that.argv_ = nullptr;
65     return *this;
66   }
67
68   int    argc()            const { return argc_; }
69   char** argv()                  { return argv_; }
70   const char*const* argv() const { return argv_; }
71   char* operator[](std::size_t i) { return argv_[i]; }
72 };
73
74 }
75 }
76
77 static
78 std::function<void()> wrap_main(xbt_main_func_t code, int argc, char **argv)
79 {
80   if (code) {
81     auto arg = std::make_shared<simgrid::simix::args>(argc, argv);
82     return [=]() {
83       code(arg->argc(), arg->argv());
84     };
85   } else return std::function<void()>();
86 }
87
88 /**
89  * \brief creates a new context for a user level process
90  * \param code a main function
91  * \param argc the number of arguments of the main function
92  * \param argv the vector of arguments of the main function
93  * \param cleanup_func the function to call when the context stops
94  * \param cleanup_arg the argument of the cleanup_func function
95  */
96 smx_context_t SIMIX_context_new(
97   xbt_main_func_t code, int argc, char **argv,
98   void_pfn_smxprocess_t cleanup_func,
99   smx_process_t simix_process)
100 {
101   if (!simix_global)
102     xbt_die("simix is not initialized, please call MSG_init first");
103   return simix_global->context_factory->create_context(
104     wrap_main(code, argc, argv), cleanup_func, simix_process);
105 }
106
107 namespace simgrid {
108 namespace simix {
109
110 ContextFactoryInitializer factory_initializer = nullptr;
111
112 ContextFactory::~ContextFactory() {}
113
114 Context* ContextFactory::self()
115 {
116   return SIMIX_context_get_current();
117 }
118
119 void ContextFactory::declare_context(void* context, std::size_t size)
120 {
121 #ifdef HAVE_MC
122   /* Store the address of the stack in heap to compare it apart of heap comparison */
123   if(MC_is_active())
124     MC_ignore_heap(context, size);
125 #endif
126 }
127
128 Context::Context(std::function<void()> code,
129     void_pfn_smxprocess_t cleanup_func, smx_process_t process)
130   : code_(std::move(code)), process_(process), iwannadie(false)
131 {
132   /* If the user provided a function for the process then use it.
133      Otherwise, it is the context for maestro and we should set it as the
134      current context */
135   if (has_code())
136     this->cleanup_func_ = cleanup_func;
137   else
138     SIMIX_context_set_current(this);
139 }
140
141 Context::~Context()
142 {
143 }
144
145 void Context::stop()
146 {
147   if (this->cleanup_func_)
148     this->cleanup_func_(this->process_);
149   this->process_->suspended = 0;
150
151   this->iwannadie = false;
152   simcall_process_cleanup(this->process_);
153   this->iwannadie = true;
154 }
155
156 }
157 }