AnubisProcess.h
10.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
#ifndef __CM_ANUBIS_PROCESS_H__
#define __CM_ANUBIS_PROCESS_H__
/* see vm.cpp for explanations of this: */
#define NO_BIG_SWITCH
#define WITH_STATIC_MEMBERS
#include "AnubisSupport.h"
#include "CMList.h"
#include "vm.h"
#include "bytecode.h"
#include "Profiling.h"
#include "../../../third_dev/sqlite3/sqlite3.h"
#include "perf.h"
BEGIN_NAMESPACE(CM);
//class AnubisAllocator;
class AnubisProcess
{
public:
enum anbStatus
{
machine_not_used,
running,
waiting_for_event,
waiting_for_condition,
waiting_for_completion,
finished,
need_bigger_stack,
need_bigger_locked_files_stack,
need_more_memory,
invalid_instruction,
invalid_IP
};
enum WorkSort
{
computing,
deleting,
equaling,
serializing,
unserializing
};
AnubisProcess(void);
virtual ~AnubisProcess();
/**
* CreateProcess constructor
* @param starting_point where to begin within code
* @param byte_code code to execute
* @param code_size
* @param allocator
* @return Return the process id of new created process, otherwise -1 for error
*/
int Create(U8 * starting_IP, U8 priority, AnubisAllocator *allocator);
/**
* Set the pid of the process. usually is the process list who decide the pid of the
* process
* @param pid process unique id
*/
void SetPid(U32 pid);
void SetStatus(anbStatus);
U32 GetPid(void);
anbStatus GetStatus(void);
const struct timeval& GetStartingTime(void) const { return m_starting_time; }
//U32 GetStartingPoint(void) const { return m_starting_point; }
int GetStepCounter(void) const { return m_steps; }
U8 *GetIP(void);
U32 *GetSP(void);
U8 *GetCodeBegin(void);
U32 GetWorkSort(void);
U32 *GetSPBegin(void);
U32 *GetSPEnd(void);
U32 GetMainRegister() const { return m_R; }
U32 GetIndexRegister() const { return m_I; }
bool IsUnserialFailed() const { return m_unserial_failed; }
bool IsDUCNonEmpty() const { return m_duc_non_empty; }
U8 GetPriority() const { return m_priority; }
void SetSP(U32 * sp);
U8* GetSerializationBuffer() const { return m_serial_buf; }
U32 GetSerializationSize() const { return m_serial_size; }
U32 GetSerializationNext() const { return m_serial_next; }
AnubisAllocator *GetAllocator(void);
struct timeval * GetAlarm(void);
void PushOnSP(U32 value);
int RunMachine(int steps);
// Stack function
void EnlargeStack(void);
// void EnlargeLockedFilesStack(void);
// Profiling functions
static ArrayTemplate<FunctionSummary*> & GetFunctionsList() { return m_functions; }
static FunctionSummary * GetFunction(const String & name, int32 label, bool createIfMissing = true);
static FunctionSummary * GetFunction(int32 label);
FunctionCall * CurrentFunction() const { return m_current_function; }
// Performance functions
const bigtime_t & GetPerfSum() const { return m_perf_time_sum; }
void PerfSumTime(bigtime_t t) { m_perf_time_sum += t; }
void ResetPerfSum() { m_perf_time_sum = 0; }
U32 GetAverageLoad1() const { return (U32)(m_perf_1 * 100) >> FSHIFT; }
U32 GetAverageLoad5() const { return (U32)(m_perf_5 * 100) >> FSHIFT; }
U32 GetAverageLoad15() const { return (U32)(m_perf_15 * 100) >> FSHIFT; }
private:
bool MakeSQLite3Result(sqlite3_stmt * stmt, int error_code);
protected:
private:
U32 m_pid; /* process unique id */
anbStatus m_status; /* current status of this process */
U32 m_work_sort; /* what it is currently doing */
int m_steps; /* must be signed (((m_steps--) <= 0) in 'vm.cpp') */
U32 m_R; /* main register of the machine */
U32 m_I; /* index register of the machine */
struct timeval m_starting_time; /* keep trace of starting time for debugging purpose.*/
//U32 m_starting_point; /* keep trace of starting point for debugging purpose.*/
U8* m_IP; /* instruction pointer */
U8* m_previous_IP; /* previous value of instruction pointer */
U32 * m_SP_begin; /* address of process stack */
U32 * m_SP; /* stack pointer */
U32 * m_SP_end; /* end of process stack */
/* the two fields below droped since version 1.13. They are incompatible with the loading
of several modules, because the same process may execute code from different modules.
(the same is true of 'm_starting_point' above) */
//U8 * m_code_begin; /* address of code */
//U8 * m_code_end; /* end of code */
AnubisAllocator *m_allocator; /* memory allocator */
U32 m_DUC1; /* datum under construction 1 */
U32 m_DUC2; /* datum under construction 2 */
U32 m_DUC3; /* datum under construction 3 */
double m_DUC1d; /* datum under construction double 1 */
struct timeval m_alarm;
pid_t m_child; /* used by the 'execute' primitive */
U8 * m_serial_buf; /* serialization buffer */
U32 m_serial_size; /* current size of buffer */
U32 m_serial_next; /* current next free position */
unsigned int m_unserial_failed:1; /* flag for unserialization control */
unsigned int m_duc_non_empty:1; /* flag for control of DUC1 DUC2 and DUC3 */
// U32 m_locked_files_stack_size; /* current size of locked files stack */
// U32 m_locked_files_SP; /* locked files stack pointer */
// U32 * m_locked_files; /* stack of locked files (vm strings) */
U8 m_priority; // current priority of the process
#ifdef instruction_count
U32 m_i_count[256]; /* one counter for each instruction */
#endif
FunctionCall * m_current_function; // used by profiling instructions (begin_op and end_op)
static ArrayTemplate<FunctionSummary*> m_functions;
// performance
bigtime_t m_perf_time_sum;
public:
U32 m_perf_1;
U32 m_perf_5;
U32 m_perf_15;
#ifdef NO_BIG_SWITCH
/* Declaration of all instructions of the VM as member functions.
ci_ is used for 'computing'
si_ is used for 'serializing'
ui_ is used for 'unserializing'
'normal_instructions_list' and 'pseudo_instructions_list' are #defined in
'anubis_dev/include/bytecode.h'. */
#ifdef WITH_STATIC_MEMBERS
/* member functions are static and the process is passed explicitly */
#define STKW static
#define EARG AnubisProcess *
#else
/* member functions are instance functions and the process is implicit */
#define STKW
#define EARG void
#endif
/* computing */
#define item(n) STKW void ci_##n(EARG);
common_instructions_list
normal_instructions_list
pseudo_instructions_list
#undef item
STKW void ci_dummy(EARG);
/* serializing */
#define item(n) STKW void serialize_##n(EARG);
common_instructions_list
normal_instructions_list
pseudo_instructions_list
#undef item
STKW void serialize_dummy(EARG);
/* unserializing */
#define item(n) STKW void ui_##n(EARG);
common_instructions_list
normal_instructions_list
pseudo_instructions_list
#undef item
STKW void ui_dummy(EARG);
/* The macros which are needed for declaring the above functions in .cpp files: */
#ifdef NO_BIG_SWITCH
#ifdef WITH_STATIC_MEMBERS
#define MAM(m) (this_one->m)
#define ci_decl(n) void AnubisProcess::ci_##n(AnubisProcess *this_one)
#define si_decl(n) void AnubisProcess::serialize_##n(AnubisProcess *this_one)
#define ui_decl(n) void AnubisProcess::ui_##n(AnubisProcess *this_one)
#else
#define MAM(m) (m)
#define ci_decl(n) void AnubisProcess::ci_##n(void)
#define si_decl(n) void AnubisProcess::serialize_##n(void)
#define ui_decl(n) void AnubisProcess::ui_##n(void)
#endif
#endif
/* the tables of functions */
#ifdef WITH_STATIC_MEMBERS
static void (*(ci_ftable[]))(AnubisProcess *);
static void (*(si_ftable[]))(AnubisProcess *);
static void (*(ui_ftable[]))(AnubisProcess *);
#else
void (*(ci_ftable[]))(void);
void (*(si_ftable[]))(void);
void (*(ui_ftable[]))(void);
#endif
#endif /* NO_BIG_SWITCH */
};
#ifdef NO_BIG_SWITCH
#ifdef debug_vm
#define trace if (debugging ||\
(start_end_debug &&\
(start_debug<=relative_IP((MAM(m_IP)))) &&\
((U32)(relative_IP(MAM(m_IP)))<=end_debug))) {\
int i = *(MAM(m_IP));\
LOGINFO("\n\nstack: ");\
{ U32 *p;\
for (p = MAM(m_SP)-1; p >= MAM(m_SP_begin) && p >= MAM(m_SP)-6; p--)\
LOGINFO("%.8x ",*p); }\
LOGINFO("\n%d %s steps=%d IP=%d SP=%.3d R=%.8x I=%.3d" \
" uf=%d sbuf=%d snxt=%d ssiz=%d mem=%d\n",\
MAM(m_pid), ShortString((CM::AnubisProcess::WorkSort)MAM(m_work_sort)),\
MAM(m_steps),relative_IP(MAM(m_IP)),MAM(m_SP)-MAM(m_SP_begin),MAM(m_R),MAM(m_I),\
(U32)(MAM(m_unserial_failed)),\
(U32)(MAM(m_serial_buf)),MAM(m_serial_next),MAM(m_serial_size),\
memory_in_use);\
LOGINFO(" %16s (%.3d) %.3d %.3d %.3d %.3d %.3d %.3d %.3d %.3d %.3d %.3d %.3d %.3d",\
instr_name(i,get16(1)),i,\
get8(1),get8(2),get8(3),get8(4),get8(5),get8(6),get8(7),get8(8),\
get8(9),get8(10),get8(11),get8(12));\
fflush(stdout); }
#else
#define trace
#endif
#endif
class AnubisProcessList : public List
{
public:
virtual ~AnubisProcessList();
static AnubisProcessList* GetInstance();
AnubisProcess * GetProcessAt(U32);
AnubisProcess * GetProcessByID(U32);
AnubisProcess * CreateAnubisProcess(U8 * starting_IP, U8 priority, AnubisAllocator* allocator);
void DeleteProcess(U32 pid);
AnubisProcess * GetRunningProcess() const { return _runningProcess; }
void SetRunningProcess(AnubisProcess * current) { _runningProcess = current; }
protected:
private:
AnubisProcessList();
U32 _pidCounter;
AnubisProcess * _runningProcess;
static AnubisProcessList* _instance; // instance du singleton
};
#define TheAnubisProcessList CM::AnubisProcessList::GetInstance()
END_NAMESPACE(CM);
extern "C" const char * ShortString(CM::AnubisProcess::WorkSort ws);
#endif // __CM_PROCESS_H__