Main Page   Packages   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Search  

C:/temp/src/j2k/QNX4/Fred/THREADS.TXT

Go to the documentation of this file.
00001 Hello,
00002 
00003     Here's the stuff.  It should be pretty self-explanatory.
00004 
00005     Ideally, we should have some way of encapsulating message
00006     sends/replies so we can send some buffers around rather than
00007     primitive C arrays, but right now, I'm just testing.
00008 
00009     This worked out of the box, BTW---no need to do anything
00010     bizarre (except that the C++ compiler doesn't like the bool
00011     type, so I had to make those ints).
00012 
00013     The code follows my signature.  Just 'cc thread.cc'.  It's
00014     lousy; I don't check all return values.  But then again,
00015     that's just test code, and most production code doesn't check
00016     all return values, either (I should know; I write production
00017     code during summers) :{)
00018 
00019     To whomever had an a.out in the c directory: I scrapped it,
00020     sorry. :{)  I also put the C++ code in thread.cc in the c
00021     subdirectory of our group directory (in other words,
00022     //1/home/group5/c/thread.cc)
00023 
00024     The technique should be applicable to other kinds of
00025     callbacks.  I'll work on getting support for interrupt
00026     handlers later this week.
00027 
00028     While I'm here, if you want to contact me by phone, it's
00029     (514) 351-2378.  I recommend you e-mail me instead unless it's
00030     something really, really urgent.
00031 
00032 -- 
00033 Benoit Goudreault-Emond -- Reply to: bge@crosswinds.net
00034 CoFounder, KMS Group.  Student, B. CompEng, Concordia University.
00035 A proud user of Linux---I'd rather work than nursemaid my computer.
00036 My homepage (such as it is): http://www.crosswinds.net/~bge
00037 
00038 /* Small thread experiment */
00039 
00040 #include <stdio.h>
00041 #include <stdlib.h>
00042 #include <process.h>
00043 #include <stddef.h>
00044 #include <string.h>
00045 #include <sys/kernel.h>
00046 #include <assert.h>
00047 
00048 class Thread
00049 {
00050 protected:
00051     pid_t thread_id_;
00052     static void wrapper(void* p);
00053     static const size_t stack_size;
00054 public:
00055     Thread() : thread_id_(-1) {}
00056     int start(size_t stk = stack_size);
00057     int sendmsg(void* msg, size_t mlen,
00058                 void* rcv, size_t rlen);
00059     virtual void run() = 0;
00060     virtual ~Thread() {}
00061 };
00062 
00063 const size_t Thread::stack_size = 4096;
00064 
00065 void Thread::wrapper(void* p)
00066 {
00067     Thread* self = (Thread*)p;
00068     self->run();
00069     _endthread();
00070 }
00071 
00072 int Thread::start(size_t stk)
00073 {
00074     assert(thread_id_ < 0);
00075     thread_id_ = _beginthread(Thread::wrapper, NULL, stk, this);
00076     return thread_id_;
00077 }
00078 
00079 int Thread::sendmsg(void* msg, size_t mlen, void* rcv, size_t rlen)
00080 {
00081     assert(thread_id_ >= 0);
00082     return Send(thread_id_, msg, rcv, mlen, rlen);
00083 }
00084 
00085 
00086 /* Test thread class --- grabs messages and prints them
00087 
00088    "ERROR" is recognized as a message that means we want ERROR back
00089    "END" is recognized as a message that means you must exit
00090  */
00091 
00092 class DisplayThread : public Thread
00093 {
00094 private:
00095     char buffer_[256];           // message buffer
00096     static const char* ok_response;
00097     static const char* error_response;
00098     
00099     virtual void run();
00100 };
00101 
00102 const char* DisplayThread::ok_response = "OK\n";
00103 const char* DisplayThread::error_response = "ERROR\n";
00104 
00105 void DisplayThread::run()
00106 {
00107     pid_t pid;
00108     while(1)
00109     {
00110         const char* response;
00111         
00112         if((pid = Receive(0, buffer_, sizeof(buffer_))) < 0)
00113         {
00114             printf("ERROR--code %d\n", errno);
00115             return;
00116         }
00117         // make sure it's NUL terminated
00118         buffer_[sizeof(buffer_)-1] = '\0';
00119         // check message contents
00120         if(!strcmp(buffer_, "ERROR"))
00121             response = error_response;
00122         else if(!strcmp(buffer_, "END"))
00123             break;              // response sent below
00124         else
00125             response = ok_response;
00126             
00127         printf("Got from %d: %s\n", pid, buffer_);
00128         // send back
00129         Reply(pid, response, strlen(response)+1);
00130     }
00131     // send response and die
00132     Reply(pid, ok_response, sizeof(ok_response));
00133 }
00134         
00135 
00136 // test
00137 int main()
00138 {
00139     DisplayThread thread;
00140     char buffer[256], recv[256];
00141 
00142     if(thread.start() < 0)
00143     {
00144         printf("UUURGH! Thread could not start! (%d)\n", errno);
00145         return 1;
00146     }
00147 
00148     // print our banner and such
00149     while(1)
00150     {
00151         
00152         printf("Message to send (END to end): ");
00153         fgets(buffer, sizeof(buffer), stdin);
00154         int len = strlen(buffer);
00155         if(buffer[len-1] == '\n')
00156         {
00157             buffer[len-1] = '\0';
00158             --len;
00159         }
00160         thread.sendmsg(buffer, len+1, recv, sizeof(recv));
00161         printf("Got back: %s", recv);
00162         if(!strcmp(buffer, "END"))
00163             break;
00164     }
00165     return 0;
00166 }

Generated on Sun Oct 14 18:46:41 2001 for Standard J2K Library by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001