Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
use namespaces
[simgrid.git] / src / kernel / activity / CommImpl.cpp
1 /* Copyright (c) 2007-2019. The SimGrid Team. All rights reserved.          */
2
3 /* This program is free software; you can redistribute it and/or modify it
4  * under the terms of the license (GNU LGPL) which comes with this package. */
5
6 #include "src/kernel/activity/CommImpl.hpp"
7 #include "simgrid/kernel/resource/Action.hpp"
8 #include "simgrid/modelchecker.h"
9 #include "src/kernel/activity/MailboxImpl.hpp"
10 #include "src/mc/mc_replay.hpp"
11 #include "src/simix/smx_network_private.hpp"
12 #include "src/surf/surf_interface.hpp"
13
14 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix_network);
15 namespace simgrid {
16 namespace kernel {
17 namespace activity {
18
19 CommImpl::CommImpl(e_smx_comm_type_t _type) : type(_type)
20 {
21   state_   = SIMIX_WAITING;
22   src_data_ = nullptr;
23   dst_data_ = nullptr;
24   XBT_DEBUG("Create comm activity %p", this);
25 }
26
27 CommImpl::~CommImpl()
28 {
29   XBT_DEBUG("Really free communication %p", this);
30
31   cleanupSurf();
32
33   if (detached && state_ != SIMIX_DONE) {
34     /* the communication has failed and was detached:
35      * we have to free the buffer */
36     if (clean_fun)
37       clean_fun(src_buff_);
38     src_buff_ = nullptr;
39   }
40
41   if (mbox)
42     mbox->remove(this);
43 }
44
45 void CommImpl::suspend()
46 {
47   /* FIXME: shall we suspend also the timeout synchro? */
48   if (surf_action_)
49     surf_action_->suspend();
50   /* if not created yet, the action will be suspended on creation, in SIMIX_comm_start() */
51 }
52
53 void CommImpl::resume()
54 {
55   /*FIXME: check what happen with the timeouts */
56   if (surf_action_)
57     surf_action_->resume();
58   /* in the other case, the synchro were not really suspended yet, see SIMIX_comm_suspend() and SIMIX_comm_start() */
59 }
60
61 void CommImpl::cancel()
62 {
63   /* if the synchro is a waiting state means that it is still in a mbox so remove from it and delete it */
64   if (state_ == SIMIX_WAITING) {
65     mbox->remove(this);
66     state_ = SIMIX_CANCELED;
67   } else if (not MC_is_active() /* when running the MC there are no surf actions */
68              && not MC_record_replay_is_active() && (state_ == SIMIX_READY || state_ == SIMIX_RUNNING)) {
69
70     surf_action_->cancel();
71   }
72 }
73
74 /**  @brief get the amount remaining from the communication */
75 double CommImpl::remains()
76 {
77   return surf_action_->get_remains();
78 }
79
80 /** @brief This is part of the cleanup process, probably an internal command */
81 void CommImpl::cleanupSurf()
82 {
83   if (surf_action_) {
84     surf_action_->unref();
85     surf_action_ = nullptr;
86   }
87
88   if (src_timeout_) {
89     src_timeout_->unref();
90     src_timeout_ = nullptr;
91   }
92
93   if (dst_timeout_) {
94     dst_timeout_->unref();
95     dst_timeout_ = nullptr;
96   }
97 }
98
99 void CommImpl::post()
100 {
101   /* Update synchro state */
102   if (src_timeout_ && src_timeout_->get_state() == resource::Action::State::FINISHED)
103     state_ = SIMIX_SRC_TIMEOUT;
104   else if (dst_timeout_ && dst_timeout_->get_state() == resource::Action::State::FINISHED)
105     state_ = SIMIX_DST_TIMEOUT;
106   else if (src_timeout_ && src_timeout_->get_state() == resource::Action::State::FAILED)
107     state_ = SIMIX_SRC_HOST_FAILURE;
108   else if (dst_timeout_ && dst_timeout_->get_state() == resource::Action::State::FAILED)
109     state_ = SIMIX_DST_HOST_FAILURE;
110   else if (surf_action_ && surf_action_->get_state() == resource::Action::State::FAILED) {
111     state_ = SIMIX_LINK_FAILURE;
112   } else
113     state_ = SIMIX_DONE;
114
115   XBT_DEBUG("SIMIX_post_comm: comm %p, state %d, src_proc %p, dst_proc %p, detached: %d", this, (int)state_,
116             src_actor_.get(), dst_actor_.get(), detached);
117
118   /* destroy the surf actions associated with the Simix communication */
119   cleanupSurf();
120
121   /* if there are simcalls associated with the synchro, then answer them */
122   if (not simcalls_.empty()) {
123     SIMIX_comm_finish(this);
124   }
125 }
126
127 } // namespace activity
128 } // namespace kernel
129 } // namespace simgrid