- int ctx_addr[CTX_ADDR_LEN]{};
- memcpy(ctx_addr, &arg, sizeof arg);
- makecontext(ucp, (void (*)())func, 2, ctx_addr[0], ctx_addr[1]);
+ return new_context<UContext>(std::move(code), cleanup, actor, this);
+}
+
+
+// UContext
+
+UContext::UContext(std::function<void()> code, void_pfn_smxprocess_t cleanup_func, smx_actor_t actor,
+ SwappedContextFactory* factory)
+ : SwappedContext(std::move(code), cleanup_func, actor, factory)
+{
+ /* if the user provided a function for the actor then use it. If not, nothing to do for maestro. */
+ if (has_code()) {
+ getcontext(&this->uc_);
+ this->uc_.uc_link = nullptr;
+ this->uc_.uc_stack.ss_sp = sg_makecontext_stack_addr(get_stack());
+ this->uc_.uc_stack.ss_size = sg_makecontext_stack_size(smx_context_usable_stack_size);
+ // Makecontext expects integer arguments; we want to pass a pointer.
+ // This context address is decomposed into a serie of integers, which are passed as arguments to makecontext.
+
+ int ctx_addr[CTX_ADDR_LEN]{};
+ UContext* arg = this;
+ memcpy(ctx_addr, &arg, sizeof this);
+ makecontext(&this->uc_, (void (*)())smx_ctx_wrapper, 2, ctx_addr[0], ctx_addr[1]);
+
+#if SIMGRID_HAVE_MC
+ if (MC_is_active()) {
+ MC_register_stack_area(get_stack(), actor, &(this->uc_), smx_context_usable_stack_size);
+ }
+#endif
+ }