NCBI C++ ToolKit
srv_tasks.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: srv_tasks.cpp 83741 2018-09-14 12:35:21Z gouriano $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Author: Pavel Ivanov
27  *
28  */
29 
30 #include "task_server_pch.hpp"
31 
32 #include "scheduler.hpp"
33 #include "srv_stat.hpp"
34 
36 
37 #if __NC_TASKS_MONITOR
38 static CMiniMutex s_all_tasks_lock;
39 #if __NC_TASKS_INTR_SET
40 struct SrvTaskCompare
41 {
42  bool operator() (const CSrvTask& x, const CSrvTask& y) const
43  {
44  return &x < &y;
45  }
46 };
47 #if 0
48 typedef intr::set< CSrvTask, intr::compare< SrvTaskCompare > > TAllTasksSet;
49 #else
50 typedef intr::member_hook<CSrvTask, intr::set_member_hook<>, &CSrvTask::m_intr_member_hook> TAllTasksSetOption;
51 typedef intr::set< CSrvTask, TAllTasksSetOption, intr::compare< SrvTaskCompare > > TAllTasksSet;
52 #endif
53 #else
54 typedef std::set<const CSrvTask*> TAllTasksSet;
55 #endif
56 
57 TAllTasksSet s_all_tasks;
58 #endif
59 
61  : m_LastThread(0),
62  m_TaskFlags(0),
63  m_LastActive(CSrvTime::CurSecs()),
64  m_Priority(GetDefaultTaskPriority()),
65  m_DiagCtx(NULL),
66  m_DiagChain(NULL),
67  m_DiagChainSize(0),
68  m_Timer(NULL)
69 {
70 #if __NC_TASKS_MONITOR
71  s_all_tasks_lock.Lock();
72 #if __NC_TASKS_INTR_SET
73  s_all_tasks.insert(*this);
74 #else
75  s_all_tasks.insert(this);
76 #endif
77  s_all_tasks_lock.Unlock();
78  m_TaskName = "CSrvTask";
79 #endif
80 }
81 
83 {
87  m_DiagChainSize = 0;
88 #if __NC_TASKS_MONITOR
89  s_all_tasks_lock.Lock();
90 #if __NC_TASKS_INTR_SET
91  s_all_tasks.erase(*this);
92 #else
93  s_all_tasks.erase(this);
94 #endif
95  s_all_tasks_lock.Unlock();
96 #endif
97 }
98 
99 void
101 {
103  ExecuteSlice(thr_num);
105 }
106 
107 #if __NC_TASKS_MONITOR
109 {
110  string is("\": "), eol(",\n\"");
111  map<string, int> idle_tasks;
112  map<string, CSrvStatTerm<int>> busy_tasks;
113  size_t len = 0;
114 
115  s_all_tasks_lock.Lock();
116  int now = CSrvTime::CurSecs();
117  ITERATE(TAllTasksSet, t, s_all_tasks) {
118 #if __NC_TASKS_INTR_SET
119  const CSrvTask* job = &*t;
120 #else
121  const CSrvTask* job = *t;
122 #endif
123  if (busy_tasks.find(job->m_TaskName) == busy_tasks.end()) {
124  busy_tasks[job->m_TaskName].Initialize();
125  }
126  if (idle_tasks.find(job->m_TaskName) == idle_tasks.end()) {
127  idle_tasks[job->m_TaskName] = 0;
128  }
129  if (job->m_LastActive != 0) {
130  busy_tasks[job->m_TaskName].AddValue(max(0, now - job->m_LastActive));
131  } else {
132  ++idle_tasks[job->m_TaskName];
133  }
134  len = max(len, job->m_TaskName.size());
135  }
136  s_all_tasks_lock.Unlock();
137 
138  task.WriteText(eol).WriteText("cnt_tasks").WriteText(is).WriteNumber(s_all_tasks.size());
139  for (map<string, CSrvStatTerm<int>>::const_iterator t = busy_tasks.begin(); t != busy_tasks.end(); ++t) {
140  task.WriteText(eol).WriteText(t->first).WriteText(is).WriteText(string( len - t->first.size(), ' ')).WriteText("{ \"");
141  task.WriteText("cnt").WriteText(is).WriteNumber(t->second.GetCount());
142  task.WriteText(", \"").WriteText("avg").WriteText(is).WriteNumber(t->second.GetAverage());
143  task.WriteText(", \"").WriteText("max").WriteText(is).WriteNumber(t->second.GetMaximum());
144  task.WriteText(", \"").WriteText("idle").WriteText(is).WriteNumber(idle_tasks.at(t->first));
145  task.WriteText("}");
146  }
147 }
148 #endif
149 
151  : m_TransState(eState_Initial)
152 {
153 #if __NC_TASKS_MONITOR
154  m_TaskName = "CSrvTransitionTask";
155 #endif
156 }
157 
159 {
160  if (m_TransState == eState_Transition || !m_Consumers.empty()) {
161  SRV_FATAL("CSrvTransitionTask destructor unexpected: m_TransState: "
162  << m_TransState << ", Consumers: " << m_Consumers.size());
163  }
164 }
165 
166 void
168 {
169  m_TransLock.Lock();
170  switch (m_TransState) {
171  case eState_Initial:
173  consumer->m_TransFinished = false;
174  m_Consumers.push_front(*consumer);
176  SetRunnable();
177  break;
178  case eState_Transition:
179  consumer->m_TransFinished = false;
180  m_Consumers.push_front(*consumer);
182  break;
183  case eState_Final:
185  consumer->m_TransFinished = true;
186  consumer->SetRunnable();
187  break;
188  default:
189  SRV_FATAL("Unsupported transition state: " << m_TransState);
190  }
191 }
192 
193 void
195 {
196  TSrvConsList cons_list;
197 
198  m_TransLock.Lock();
200  SRV_FATAL("Unexpected transition state: " << m_TransState);
201  }
203  cons_list.swap(m_Consumers);
205 
206  while (!cons_list.empty()) {
207  CSrvTransConsumer* consumer = &cons_list.front();
208  cons_list.pop_front();
209  consumer->m_TransFinished = true;
210  consumer->SetRunnable();
211  }
212 }
213 
214 void
216 {
217  m_TransLock.Lock();
218  if (m_TransState != eState_Final)
219  m_Consumers.erase(m_Consumers.iterator_to(*consumer));
221 }
222 
223 
225  : m_TransFinished(false)
226 {
227 #if __NC_TASKS_MONITOR
228  m_TaskName = "CSrvTransConsumer";
229 #endif
230 }
231 
233 {}
234 
Uint4 GetDefaultTaskPriority(void)
Definition: scheduler.cpp:587
Mutex created to have minimum possible size (its size is 4 bytes) and to sleep using kernel capabilit...
Definition: srv_sync.hpp:193
void Unlock(void)
Unlock the mutex.
Definition: srv_sync.cpp:119
void Lock(void)
Lock the mutex.
Definition: srv_sync.cpp:108
Task controlling a socket.
CSrvSocketTask & WriteText(CTempString message)
Write text into socket.
CSrvSocketTask & WriteNumber(NumType num)
Write number into socket as string, i.e.
Main working entity in TaskServer.
Definition: srv_tasks.hpp:88
TSrvTaskFlags m_TaskFlags
Bit-OR of flags for this task.
Definition: srv_tasks.hpp:209
int m_LastActive
Time (in seconds) when the task was active last time, i.e.
Definition: srv_tasks.hpp:212
virtual ~CSrvTask(void)
Definition: srv_tasks.cpp:82
static void PrintState(CSrvSocketTask &task)
CRequestContext ** m_DiagChain
Nested diagnostic contexts of this task.
Definition: srv_tasks.hpp:221
STimerTicket * m_Timer
Timer ticket assigned to this task when it calls RunAfter().
Definition: srv_tasks.hpp:225
size_t m_DiagChainSize
Definition: srv_tasks.hpp:223
CRequestContext * m_DiagCtx
Current diagnostic context for this task.
Definition: srv_tasks.hpp:216
CSrvTask(void)
Definition: srv_tasks.cpp:60
virtual void ExecuteSlice(TSrvThreadNum thr_num)=0
This is the main method to do all work this task should do.
void SetRunnable(bool boost=false)
Set this task "runnable", i.e.
Definition: scheduler.cpp:618
virtual void InternalRunSlice(TSrvThreadNum thr_num)
This is the real time slice execution method called from TaskServer.
Definition: srv_tasks.cpp:100
Class incorporating convenient methods to work with struct timespec.
Definition: srv_time.hpp:61
static int CurSecs(void)
Current time in seconds since epoch (time_t).
Consumer of notification about transition completeness in CSrvTransitionTask.
Definition: srv_tasks.hpp:424
virtual ~CSrvTransConsumer(void)
Definition: srv_tasks.cpp:232
bool m_TransFinished
Flag showing that transition was already consumed.
Definition: srv_tasks.hpp:443
virtual ~CSrvTransitionTask(void)
Definition: srv_tasks.cpp:158
void RequestTransition(CSrvTransConsumer *consumer)
Requests task's state transition with the provided consumer to be notified when transition is finishe...
Definition: srv_tasks.cpp:167
void FinishTransition(void)
Finish the transition process and change task's state from "Transition" to "Final" with notification ...
Definition: srv_tasks.cpp:194
CMiniMutex m_TransLock
Mutex to protect state changing.
Definition: srv_tasks.hpp:408
TSrvConsList m_Consumers
Consumers waiting for transition to complete.
Definition: srv_tasks.hpp:412
ETransState m_TransState
Current state of the task.
Definition: srv_tasks.hpp:410
void CancelTransRequest(CSrvTransConsumer *consumer)
Cancel transition request from the provided consumer.
Definition: srv_tasks.cpp:215
const_iterator begin() const
Definition: map.hpp:151
const_iterator end() const
Definition: map.hpp:152
const_iterator find(const key_type &key) const
Definition: map.hpp:153
#define false
Definition: bool.h:36
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
#define NULL
Definition: ncbistd.hpp:225
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
int len
EIPRangeType t
Definition: ncbi_localip.c:101
T max(T x_, T y_)
#define SRV_FATAL(msg)
Definition: srv_diag.hpp:173
intr::list< CSrvTransConsumer, intr::base_hook< TSrvConsListHook >, intr::constant_time_size< false > > TSrvConsList
Definition: srv_tasks.hpp:363
Uint2 TSrvThreadNum
Type for thread number in TaskServer.
Definition: task_server.hpp:42
@ fTaskOnTimer
Definition: task_server.hpp:50
#define _ASSERT
void free(voidpf ptr)
Modified on Wed Sep 04 15:01:20 2024 by modify_doxy.py rev. 669887