| 882 | } |
| 883 | |
| 884 | void RuntimeProfileBase::ComputeTimeInProfile() { |
| 885 | // Recurse on children. After this, childrens' total time is up to date. |
| 886 | int64_t children_total_time = 0; |
| 887 | { |
| 888 | lock_guard<SpinLock> l(children_lock_); |
| 889 | for (int i = 0; i < children_.size(); ++i) { |
| 890 | children_[i].first->ComputeTimeInProfile(); |
| 891 | children_total_time += children_[i].first->total_time(); |
| 892 | } |
| 893 | } |
| 894 | // IMPALA-5200: Take the max, because the parent includes all of the time from the |
| 895 | // children, whether or not its total time counter has been updated recently enough |
| 896 | // to see this. |
| 897 | int64_t total_time_ns = max(children_total_time, total_time_counter()->value()); |
| 898 | |
| 899 | // If a local time counter exists, use its value as local time. Otherwise, derive the |
| 900 | // local time from total time and the child time. |
| 901 | int64_t local_time_ns = 0; |
| 902 | bool has_local_time_counter = false; |
| 903 | { |
| 904 | lock_guard<SpinLock> l(counter_map_lock_); |
| 905 | CounterMap::const_iterator itr = counter_map_.find(LOCAL_TIME_COUNTER_NAME); |
| 906 | if (itr != counter_map_.end()) { |
| 907 | local_time_ns = itr->second->value(); |
| 908 | has_local_time_counter = true; |
| 909 | } |
| 910 | } |
| 911 | |
| 912 | if (!has_local_time_counter) { |
| 913 | local_time_ns = total_time_ns - children_total_time; |
| 914 | local_time_ns -= inactive_timer()->value(); |
| 915 | } |
| 916 | // Counters have some margin, set to 0 if it was negative. |
| 917 | local_time_ns = ::max<int64_t>(0, local_time_ns); |
| 918 | double local_time_frac = |
| 919 | min(1.0, static_cast<double>(local_time_ns) / total_time_ns); |
| 920 | total_time_ns_.Store(total_time_ns); |
| 921 | local_time_ns_.Store(local_time_ns); |
| 922 | local_time_frac_.Store(BitcastToInt64(local_time_frac)); |
| 923 | } |
| 924 | |
| 925 | void RuntimeProfile::AddChild( |
| 926 | RuntimeProfileBase* child, bool indent, RuntimeProfile* loc) { |