Process.cpp

Go to the documentation of this file.
00001 /*
00002 Copyright (C) 2003-2005 The Pentagram team
00003 
00004 This program is free software; you can redistribute it and/or
00005 modify it under the terms of the GNU General Public License
00006 as published by the Free Software Foundation; either version 2
00007 of the License, or (at your option) any later version.
00008 
00009 This program is distributed in the hope that it will be useful,
00010 but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 GNU General Public License for more details.
00013 
00014 You should have received a copy of the GNU General Public License
00015 along with this program; if not, write to the Free Software
00016 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00017 */
00018 
00019 #include "pent_include.h"
00020 
00021 #include "Process.h"
00022 #include "Kernel.h"
00023 #include "IDataSource.h"
00024 #include "ODataSource.h"
00025 
00026 // p_dynamic_cast stuff
00027 DEFINE_RUNTIME_CLASSTYPE_CODE_BASE_CLASS(Process);
00028 
00029 DEFINE_CUSTOM_MEMORY_ALLOCATION(Process);
00030 
00031 Process::Process(ObjId it, uint16 ty)
00032         : pid(0xFFFF), flags(0), item_num(it), type(ty), result(0)
00033 {
00034         Kernel::get_instance()->assignPID(this);
00035 }
00036 
00037 void Process::fail()
00038 {
00039         assert(!(flags & PROC_TERMINATED));
00040 
00041         flags |= PROC_FAILED;
00042         terminate();
00043 }
00044 
00045 void Process::terminate()
00046 {
00047         assert(!(flags & PROC_TERMINATED));
00048 
00049         Kernel *kernel = Kernel::get_instance();
00050 
00051         // wake up waiting processes
00052         for (std::vector<ProcId>::iterator i = waiting.begin();
00053                  i != waiting.end(); ++i)
00054         {
00055                 Process *p = kernel->getProcess(*i);
00056                 if (p)
00057                         p->wakeUp(result);
00058         }
00059         waiting.clear();
00060 
00061         flags |= PROC_TERMINATED;
00062 }
00063 
00064 void Process::wakeUp(uint32 result_)
00065 {
00066         result = result_;
00067 
00068         flags &= ~PROC_SUSPENDED;
00069 
00070         Kernel::get_instance()->setNextProcess(this);
00071 }
00072 
00073 void Process::waitFor(ProcId pid_)
00074 {
00075         if (pid_) {
00076                 Kernel *kernel = Kernel::get_instance();
00077                 
00078                 // add this process to waiting list of process pid_
00079                 Process *p = kernel->getProcess(pid_);
00080                 assert(p);
00081                 p->waiting.push_back(pid);
00082         }
00083 
00084         flags |= PROC_SUSPENDED;
00085 }
00086 
00087 void Process::waitFor(Process* proc)
00088 {
00089         ProcId pid_ = 0;
00090         if (proc) pid_ = proc->getPid();
00091 
00092         waitFor(pid_);
00093 }
00094 
00095 void Process::suspend()
00096 {
00097         flags |= PROC_SUSPENDED;
00098 }
00099 
00100 void Process::dumpInfo()
00101 {
00102         pout << "Process " << getPid() << " class "
00103                  << GetClassType().class_name << ", item " << item_num
00104                  << ", type " << std::hex << type << std::dec << ", status ";
00105         if (flags & PROC_ACTIVE) pout << "A";
00106         if (flags & PROC_SUSPENDED) pout << "S";
00107         if (flags & PROC_TERMINATED) pout << "T";
00108         if (flags & PROC_TERM_DEFERRED) pout << "t";
00109         if (flags & PROC_FAILED) pout << "F";
00110         if (flags & PROC_RUNPAUSED) pout << "R";
00111         if (!waiting.empty()) {
00112                 pout << ", notify: ";
00113                 for (std::vector<ProcId>::iterator i = waiting.begin();
00114                          i != waiting.end(); ++i)
00115                 {
00116                         if (i != waiting.begin()) pout << ", ";
00117                         pout << *i;
00118                 }
00119         }
00120         pout << std::endl;
00121 }
00122 
00123 void Process::save(ODataSource* ods)
00124 {
00125         writeProcessHeader(ods);
00126         saveData(ods); // virtual
00127 }
00128 
00129 void Process::writeProcessHeader(ODataSource* ods)
00130 {
00131         const char* cname = GetClassType().class_name; // virtual
00132         uint16 clen = strlen(cname);
00133 
00134         ods->write2(clen);
00135         ods->write(cname, clen);
00136 }
00137 
00138 void Process::saveData(ODataSource* ods)
00139 {
00140         ods->write2(pid);
00141         ods->write4(flags);
00142         ods->write2(item_num);
00143         ods->write2(type);
00144         ods->write4(result);
00145         ods->write4(waiting.size());
00146         for (unsigned int i = 0; i < waiting.size(); ++i)
00147                 ods->write2(waiting[i]);
00148 }
00149 
00150 bool Process::loadData(IDataSource* ids, uint32 version)
00151 {
00152         pid = ids->read2();
00153         flags = ids->read4();
00154         item_num = ids->read2();
00155         type = ids->read2();
00156         result = ids->read4();
00157         uint32 waitcount = ids->read4();
00158         waiting.resize(waitcount);
00159         for (unsigned int i = 0; i < waitcount; ++i)
00160                 waiting[i] = ids->read2();
00161 
00162         return true;
00163 }

Generated on Fri Jul 27 22:27:30 2007 for pentagram by  doxygen 1.4.7