Merge branch 'master' into bgq_ramdisk_io
[dyninst.git] / proccontrol / src / bluegeneq.h
1 /*
2  * See the dyninst/COPYRIGHT file for copyright information.
3  * 
4  * We provide the Paradyn Tools (below described as "Paradyn")
5  * on an AS IS basis, and do not warrant its validity or performance.
6  * We reserve the right to update, modify, or discontinue this
7  * software at any time.  We shall have no obligation to supply such
8  * updates or modifications or any other form of support to you.
9  * 
10  * By your use of Paradyn, you understand and agree that we (or any
11  * other person or entity with proprietary rights in Paradyn) are
12  * under no obligation to provide either maintenance services,
13  * update services, notices of latent defects, or correction of
14  * defects for Paradyn.
15  * 
16  * This library is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU Lesser General Public
18  * License as published by the Free Software Foundation; either
19  * version 2.1 of the License, or (at your option) any later version.
20  * 
21  * This library is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24  * Lesser General Public License for more details.
25  * 
26  * You should have received a copy of the GNU Lesser General Public
27  * License along with this library; if not, write to the Free Software
28  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29  */
30
31 #include "proccontrol/h/Generator.h"
32 #include "proccontrol/h/Decoder.h"
33 #include "proccontrol/h/PCErrors.h"
34 #include "proccontrol/src/int_process.h"
35 #include "proccontrol/src/processplat.h"
36 #include "proccontrol/src/sysv.h"
37 #include "proccontrol/src/ppc_process.h"
38 #include "proccontrol/src/procpool.h"
39 #include "proccontrol/src/int_thread_db.h"
40 #include "proccontrol/src/mmapalloc.h"
41 #include "proccontrol/src/resp.h"
42
43 #include "ramdisk/include/services/MessageHeader.h"
44 #include "ramdisk/include/services/ToolctlMessages.h"
45
46 #include <queue>
47 #include <set>
48 #include <map>
49 #include <vector>
50
51 using namespace bgcios;
52 using namespace toolctl;
53
54 namespace bgq 
55 {
56
57 class bgq_process;
58 class bgq_thread;
59 class ComputeNode;
60 class ArchEventBGQ;
61 class HandlePreControlAuthority;
62 class HandlePostControlAuthority;
63
64 template <class CmdType, class AckType> class Transaction;
65
66 class bgq_process : 
67    public sysv_process,
68    public thread_db_process,
69    public ppc_process,
70    public hybrid_lwp_control_process,
71    public mmap_alloc_process,
72    public int_multiToolControl,
73    public int_signalMask,
74    public int_callStackUnwinding,
75    public int_BGQData,
76    public int_remoteIO
77 {
78    friend class ComputeNode;
79    friend class HandlerBGQStartup;
80    friend class HandlePreControlAuthority;
81    friend class HandlePostControlAuthority;
82    friend class DecoderBlueGeneQ;
83    friend class bgq_thread;
84   private:
85    static bool sendMessage(const ToolMessage &msg, uint16_t msg_type, uint32_t rank,
86                            response::ptr resp);
87
88    bool sendCommand(const ToolCommand &cmd, uint16_t cmd_type, response::ptr resp = response::ptr(), unsigned int resp_mod = 0);
89    bool sendCommand(const ToolCommand &cmd, uint16_t cmd_type, Resp::ptr resp);
90
91   public:
92    static uint32_t getCommandLength(uint16_t cmd_type, const ToolCommand &cmd);
93    static uint32_t getMessageLength(const ToolMessage &msg);
94    static uint32_t getCommandAckLength(uint16_t cmd_type, const ToolCommand &cmd);
95    static uint16_t getCommandMsgType(uint16_t cmd_id);
96    static uint16_t getCommandExpectedAck(uint16_t cmd_id);
97    static const char *bgqErrorMessage(uint32_t retcode, bool long_form = true);
98    static bool isActionCommand(uint16_t cmd_type);
99    static uint64_t getJobID();
100    static uint32_t getToolID();
101
102    bgq_process(Dyninst::PID p, std::string e, std::vector<std::string> a, 
103               vector<string> envp, std::map<int, int> f);
104    virtual ~bgq_process();
105
106    virtual bool plat_create();
107    virtual bool plat_attach(bool all_stopped, bool &needsSync);
108    virtual bool plat_forked();
109    virtual bool plat_detach(result_response::ptr resp, bool leave_stopped);
110    virtual bool plat_detachDone();
111    virtual bool plat_terminate(bool &needs_sync);
112    virtual bool needIndividualThreadAttach();
113    virtual bool getThreadLWPs(std::vector<Dyninst::LWP> &lwps);
114    virtual bool plat_getInterpreterBase(Address &base);
115    virtual bool plat_supportDOTF();
116    virtual OSType getOS() const;
117    virtual Dyninst::Architecture getTargetArch();
118    virtual unsigned int getTargetPageSize();
119    virtual Dyninst::Address plat_mallocExecMemory(Dyninst::Address, unsigned int);
120    virtual bool plat_individualRegAccess();
121    virtual bool plat_supportLWPPostDestroy();
122    virtual SymbolReaderFactory *plat_defaultSymReader();
123    virtual void noteNewDequeuedEvent(Event::ptr ev);
124    virtual unsigned int plat_getCapabilities();
125    virtual Event::ptr plat_throwEventsBeforeContinue(int_thread *thr);
126
127    void getStackInfo(bgq_thread *thr, CallStackCallback *cbs);
128    virtual bool plat_getStackInfo(int_thread *thr, stack_response::ptr stk_resp);
129    virtual bool plat_handleStackInfo(stack_response::ptr stk_resp, CallStackCallback *cbs);
130
131    virtual bool plat_waitAndHandleForProc();
132    virtual bool plat_readMem(int_thread *thr, void *local, Dyninst::Address addr, size_t size);
133    virtual bool plat_writeMem(int_thread *thr, const void *local, Dyninst::Address addr, size_t size, bp_write_t bp_write);
134    virtual bool plat_needsAsyncIO() const;
135    virtual bool plat_readMemAsync(int_thread *thr, Dyninst::Address addr, 
136                                   mem_response::ptr result);
137    virtual bool plat_writeMemAsync(int_thread *thr, const void *local, Dyninst::Address addr,
138                                    size_t size, result_response::ptr result, bp_write_t bp_write);
139    bool internal_readMem(int_thread *stop_thr, Dyninst::Address addr, 
140                          mem_response::ptr resp, int_thread *thr);
141    bool internal_writeMem(int_thread *stop_thr, const void *local, Dyninst::Address addr,
142                           size_t size, result_response::ptr result, int_thread *thr, bp_write_t bp_write);
143    virtual bool plat_needsThreadForMemOps() const;
144
145    virtual bool plat_preHandleEvent();
146    virtual bool plat_postHandleEvent();
147    virtual bool plat_preAsyncWait();
148    bool rotateTransaction();
149
150    virtual bool plat_individualRegRead();
151    virtual bool plat_individualRegSet();
152
153    virtual bool plat_getOSRunningStates(std::map<Dyninst::LWP, bool> &runningStates);
154
155    virtual bool plat_suspendThread(int_thread *thrd);
156    virtual bool plat_resumeThread(int_thread *thrd);
157    virtual bool plat_debuggerSuspended();
158    virtual void plat_threadAttachDone();
159
160    virtual LWPTracking *getLWPTracking();
161    virtual bool plat_lwpRefresh(result_response::ptr resp);
162    virtual bool plat_lwpRefreshNoteNewThread(int_thread *thr);
163
164    bool handleStartupEvent(void *data);
165    ComputeNode *getComputeNode() const;
166    uint32_t getRank();
167    void fillInToolMessage(ToolMessage &toolmsg, uint16_t msg_type, response::ptr resp = response::ptr());
168
169    bool decoderPendingStop();
170    void setDecoderPendingStop(bool b);
171
172    virtual std::string mtool_getName();
173    virtual MultiToolControl::priority_t mtool_getPriority();
174    virtual MultiToolControl *mtool_getMultiToolControl();
175
176    virtual void bgq_getProcCoordinates(unsigned &a, unsigned &b, unsigned &c, unsigned &d, unsigned &e, unsigned &t) const;
177    virtual unsigned int bgq_getComputeNodeID() const;
178    virtual void bgq_getSharedMemRange(Dyninst::Address &start, Dyninst::Address &end) const;
179    virtual void bgq_getPersistantMemRange(Dyninst::Address &start, Dyninst::Address &end) const;
180    virtual void bgq_getHeapMemRange(Dyninst::Address &start, Dyninst::Address &end) const;
181
182    virtual bool plat_getFileNames(FileSetResp_t *resp);
183    virtual bool plat_getFileStatData(std::string filename, Dyninst::ProcControlAPI::stat64_ptr *stat_results,
184                                      std::set<StatResp_t *> &resps);
185    virtual bool plat_getFileDataAsync(int_eventAsyncFileRead *fileread);
186
187    virtual bool allowSignal(int signal_no);
188    
189    virtual int threaddb_getPid();
190   private:
191    typedef Transaction<QueryMessage, QueryAckMessage> QueryTransaction;
192    typedef Transaction<UpdateMessage, UpdateAckMessage> UpdateTransaction;
193    
194    QueryTransaction *query_transaction;
195    UpdateTransaction *update_transaction;
196    ComputeNode *cn;
197    int_thread *last_ss_thread;
198    LWPTracking *lwp_tracker;
199    result_response::ptr lwp_tracking_resp;
200
201    bool hasControlAuthority;
202    bool interp_base_set;
203    bool page_size_set;
204    bool debugger_suspended;
205    bool decoder_pending_stop;
206    bool is_doing_temp_detach;
207    bool stopped_on_startup;
208    bool held_on_startup;
209    bool got_startup_stop;
210
211    uint32_t rank;
212
213    unsigned int page_size;
214    Address interp_base;
215
216    GetProcessDataAckCmd get_procdata_result;
217    GetAuxVectorsAckCmd get_auxvectors_result;
218    GetThreadListAckCmd *get_thread_list;
219
220    EventControlAuthority::ptr pending_control_authority; //Used for releasing control authority
221    int_eventControlAuthority *stopwait_on_control_authority; //Used for gaining control authority
222    std::string tooltag;
223    uint8_t priority;
224    MultiToolControl *mtool;
225    enum {
226       issue_attach = 0,
227       waitfor_attach,
228       issue_control_request,
229       waitfor_control_request_ack,
230       waitfor_control_request_notice,
231       issue_data_collection,
232       waitfor_data_or_stop,
233       skip_control_request_signal,
234       waitfor_control_request_signal,
235       waitfor_data_collection,
236       waits_done,
237       step_insn,
238       reissue_data_collection,
239       startup_done,
240       startup_donedone
241    } startup_state;
242
243    enum {
244       no_detach_issued,
245       issue_control_release,
246       control_release_sent,
247       choose_detach_mechanism,
248       issued_all_detach,
249       issued_detach,
250       waitfor_all_detach,
251       detach_cleanup,
252       detach_done
253    } detach_state;
254
255    static uint64_t jobid;
256    static uint32_t toolid;
257    static bool set_ids;
258    static bool do_all_attach;
259
260    static set<void *> held_msgs;
261    static unsigned int num_pending_stackwalks;
262 };
263
264 class bgq_thread : public thread_db_thread, public ppc_thread
265 {
266    friend class bgq_process;
267   private:
268    bool last_signaled;
269    CallStackUnwinding *unwinder;
270   public:
271    bgq_thread(int_process *p, Dyninst::THR_ID t, Dyninst::LWP l);
272    virtual ~bgq_thread();
273
274    virtual bool plat_cont();
275    virtual bool plat_stop();
276    virtual bool plat_getAllRegisters(int_registerPool &reg);
277    virtual bool plat_getRegister(Dyninst::MachRegister reg, Dyninst::MachRegisterVal &val);
278    virtual bool plat_setAllRegisters(int_registerPool &reg);
279    virtual bool plat_setRegister(Dyninst::MachRegister reg, Dyninst::MachRegisterVal val);
280    virtual bool attach();
281
282    virtual bool plat_getAllRegistersAsync(allreg_response::ptr result);
283    virtual bool plat_getRegisterAsync(Dyninst::MachRegister reg, 
284                                       reg_response::ptr result);
285    virtual bool plat_setAllRegistersAsync(int_registerPool &pool,
286                                           result_response::ptr result);
287    virtual bool plat_setRegisterAsync(Dyninst::MachRegister reg, 
288                                       Dyninst::MachRegisterVal val,
289                                       result_response::ptr result);
290    virtual bool plat_convertToSystemRegs(const int_registerPool &pool, unsigned char *regs, bool gpr_only = false);
291
292    virtual CallStackUnwinding *getStackUnwinder();
293
294    static void regBufferToPool(BG_Reg_t *gprs, BG_Special_Regs *sregs, int_registerPool &reg);
295    static void regPoolToBuffer(int_registerPool &reg, BG_Reg_t *gprs, BG_Special_Regs *sregs);
296    static void regPoolToUser(const int_registerPool &reg, void *user_area);
297    static bool genRegToSystem(MachRegister reg, GeneralRegSelect &result);
298    static bool specRegToSystem(MachRegister reg, SpecialRegSelect &result);
299 };
300
301 struct buffer_t {
302    void *buffer;
303    size_t size;
304    bool is_heap_allocated;
305    buffer_t(void *b, size_t s, bool h) :
306      buffer(b),
307      size(s),
308      is_heap_allocated(h)
309    {
310    }
311    buffer_t() :
312      buffer(NULL),
313      size(0),
314      is_heap_allocated(false)
315    {
316    }
317
318 };
319
320 class ComputeNode
321 {
322    friend class bgq_process;
323    friend class WriterThread;
324   private:
325    static std::map<int, ComputeNode *> id_to_cn;
326    static std::map<std::string, int> socket_to_id;
327    static std::set<ComputeNode *> all_compute_nodes;
328
329    static bool constructSocketToID();
330    ComputeNode(int cid);
331
332    std::set<bgq_process *> procs;
333   public:
334    static ComputeNode *getComputeNodeByID(int cn_id);
335    static ComputeNode *getComputeNodeByRank(uint32_t rank);
336
337    int getFD() const;
338    int getID() const; //The BG/Q doc calls this the 'pid', which is unfortunate naming cause 
339                       // it doesn't represent a process, but a compute node
340
341    bool writeToolMessage(bgq_process *proc, ToolMessage *msg, bool heap_alloced);
342    bool writeToolAttachMessage(bgq_process *proc, ToolMessage *msg, bool heap_alloced);
343    bool flushNextMessage();
344    bool handleMessageAck();
345
346    bool reliableWrite(void *buffer, size_t buffer_size);
347    void removeNode(bgq_process *proc);
348
349    const std::set<bgq_process *> &getProcs() const { return procs; }
350    ~ComputeNode();
351
352    static const std::set<ComputeNode *> &allNodes();
353    static void emergencyShutdown();
354   private:
355    int fd;
356    int cn_id;
357    Mutex send_lock;
358    Mutex attach_lock;
359    Mutex detach_lock;
360    bool do_all_attach;
361    bool issued_all_attach;
362    bool all_attach_done;
363    bool all_attach_error;
364
365    bool have_pending_message;
366    Mutex pending_queue_lock;
367    std::queue<buffer_t> queued_pending_msgs;
368 };
369
370 class HandleBGQStartup : public Handler
371 {
372   public:
373    HandleBGQStartup();
374    ~HandleBGQStartup();
375
376    virtual void getEventTypesHandled(vector<EventType> &etypes);
377    virtual handler_ret_t handleEvent(Event::ptr ev);
378    virtual int getPriority() const;
379 };
380
381 //Handles the notice event, while we still have CA.  Removes BPs, etc
382 class HandlePreControlAuthority : public Handler
383 {
384   public:
385    HandlePreControlAuthority();
386    ~HandlePreControlAuthority();
387
388    virtual void getEventTypesHandled(vector<EventType> &etypes);
389    virtual handler_ret_t handleEvent(Event::ptr ev);
390 };
391
392 //Handles the releasing of CA, triggers on the continue after a HandlePreControlAuthority event
393 class HandlePostControlAuthority : public Handler
394 {
395   public:
396    HandlePostControlAuthority();
397    ~HandlePostControlAuthority();
398
399    virtual void getEventTypesHandled(vector<EventType> &etypes);
400    virtual handler_ret_t handleEvent(Event::ptr ev);
401 };
402
403 class GeneratorBGQ : public GeneratorMT
404 {
405   friend class ComputeNode;
406   private:
407    int kick_pipe[2];
408    static const int kick_val = 0xfeedf00d; //0xdeadbeef is passe
409
410    bool readMessage(int fd, vector<ArchEvent *> &events);
411    bool readMessage(vector<ArchEvent *> &events, bool block);
412    bool read_multiple_msgs;
413    bool reliableRead(int fd, void *buffer, size_t buffer_size, int timeout_s = -1);
414
415  public:
416    GeneratorBGQ();
417    virtual ~GeneratorBGQ();
418
419    virtual bool initialize();
420    virtual bool canFastHandle();
421    virtual ArchEvent *getEvent(bool block);
422    virtual bool getMultiEvent(bool block, vector<ArchEvent *> &events);
423    virtual bool plat_skipGeneratorBlock();
424    void kick();
425    void shutdown();
426 };
427
428 class ArchEventBGQ : public ArchEvent
429 {
430   private:
431    ToolMessage *msg;
432    bool free_msg;
433   public:
434    ArchEventBGQ(ToolMessage *msg);
435    virtual ~ArchEventBGQ();
436
437    ToolMessage *getMsg() const;
438    void dontFreeMsg();
439 };
440
441 class DecoderBlueGeneQ : public Decoder
442 {
443   private:
444    Event::ptr decodeCompletedResponse(response::ptr resp, int_process *proc, int_thread *thrd,
445                                       map<Event::ptr, EventAsync::ptr> &async_evs);
446
447    bool decodeStartupEvent(ArchEventBGQ *ae, bgq_process *proc, 
448                            void *data, Event::SyncType stype, vector<Event::ptr> &events);
449    bool decodeUpdateOrQueryAck(ArchEventBGQ *ae, bgq_process *proc,
450                                int num_commands, CommandDescriptor *cmd_list, 
451                                vector<Event::ptr> &events);
452    bool decodeNotifyMessage(ArchEventBGQ *archevent, bgq_process *proc,
453                             vector<Event::ptr> &events);
454    bool decodeSignal(ArchEventBGQ *archevent, bgq_process *proc,
455                      vector<Event::ptr> &events);
456    bool decodeBreakpoint(ArchEventBGQ *archevent, bgq_process *proc, int_thread *thr,
457                          Address addr, vector<Event::ptr> &events);
458    bool decodeGenericSignal(ArchEventBGQ *archevent, bgq_process *proc, int_thread *thr,
459                             int signum, vector<Event::ptr> &events);
460    bool decodeStop(ArchEventBGQ *archevent, bgq_process *proc, int_thread *thr,
461                    std::vector<Event::ptr> &events);
462    bool decodeStep(ArchEventBGQ *archevent, bgq_process *proc, int_thread *thr,
463                    std::vector<Event::ptr> &events);
464    bool decodeExit(ArchEventBGQ *archevent, bgq_process *proc, std::vector<Event::ptr> &events);
465    bool decodeControlNotify(ArchEventBGQ *archevent, bgq_process *proc, std::vector<Event::ptr> &events);
466    bool decodeDetachAck(ArchEventBGQ *archevent, bgq_process *proc, std::vector<Event::ptr> &events);
467    bool decodeReleaseControlAck(ArchEventBGQ *archevent, bgq_process *proc, int err_code, std::vector<Event::ptr> &events);
468    bool decodeControlAck(ArchEventBGQ *ev, bgq_process *qproc, vector<Event::ptr> &events);
469    bool decodeLWPRefresh(ArchEventBGQ *ev, bgq_process *proc, ToolCommand *cmd);
470    bool decodeLWPRefresh(ArchEventBGQ *ev, bgq_process *proc, ToolCommand *cmd, std::vector<Event::ptr> &events);
471    bool decodeFileStat(ToolCommand *cmd, bgq_process *proc, unsigned int resp_id, int rc);
472    bool decodeFileContents(ArchEventBGQ *ev, bgq_process *proc, ToolCommand *cmd, 
473                            int rc, unsigned int resp_id, bool owns_msg,
474                            std::vector<Event::ptr> &events);
475    bool decodeGetFilenames(ArchEventBGQ *ev, bgq_process *proc, ToolCommand *cmd, int rc, int id);
476
477    bool usesResp(uint16_t cmdtype) { return (cmdtype == GetFileContentsAck); }
478
479    Event::ptr createEventDetach(bgq_process *proc, bool err);
480  public:
481    DecoderBlueGeneQ();
482    virtual ~DecoderBlueGeneQ();
483    virtual bool decode(ArchEvent *ae, std::vector<Event::ptr> &events);
484    virtual unsigned getPriority() const;
485 };
486
487 class IOThread
488 {
489   protected:
490    static void mainWrapper(void *);
491
492    IOThread();
493    ~IOThread();
494    void init();
495    void kick();
496    void thrd_main();
497    virtual void run() = 0;
498    virtual void localInit() = 0;
499    virtual void thrd_kick();
500    CondVar initLock;
501    CondVar shutdownLock;
502    bool do_exit;
503    bool init_done;
504    bool shutdown_done;
505    DThread thrd;
506    int lwp;
507    int pid;
508   public:
509    void shutdown();
510 };
511
512 class ReaderThread : public IOThread
513 {
514   protected:
515    static ReaderThread *me;
516    std::queue<buffer_t> msgs;
517    std::set<int> fds;
518    CondVar queue_lock;
519    CondVar fd_lock;
520
521    ReaderThread();
522    virtual void run();
523    virtual void localInit();
524    int kick_fd;
525    int kick_fd_write;
526   protected:
527    virtual void thrd_kick();
528   public:
529    ~ReaderThread();
530    static ReaderThread *get();
531    buffer_t readNextElement(bool block);
532    void addComputeNode(ComputeNode *cn);
533    void rmComputeNode(ComputeNode *cn);
534    void setKickPipe(int fd);
535 };
536
537 class WriterThread : public IOThread
538 {
539   private:
540    static WriterThread *me;
541    std::map<int, ComputeNode *> rank_to_cn;
542    Mutex rank_lock;
543    WriterThread();
544    virtual void run();
545    virtual void localInit();
546    
547    std::vector<int> acks;
548    std::vector<ComputeNode *> writes;
549    CondVar msg_lock;
550   protected:
551    virtual void thrd_kick();
552   public:
553    ~WriterThread();
554    static WriterThread *get();
555    void writeMessage(buffer_t buf, ComputeNode *cn);
556    void notifyAck(int rank);
557    void addProcess(bgq_process *proc);
558    void rmProcess(bgq_process *proc);
559 };
560
561
562 class DebugThread
563 {
564   private:
565    DThread debug_thread;
566    static DebugThread *me;
567    bool shutdown;
568    bool initialized;
569    int pfd[2];
570    CondVar init_lock;
571    bool init();
572    DebugThread();
573   public:
574    static DebugThread *getDebugThread();
575    ~DebugThread();
576    static void mainLoopWrapper(void *);
577    void mainLoop();
578 };
579
580
581 #include "bgq-transactions.h"
582
583 }