00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <sys/types.h>
00036 #include <unistd.h>
00037 #include "ThreadCreate.h"
00038 #include "Log.h"
00039 #include "massert.h"
00040 #include "pip_includer.h"
00041 #include "Util.h"
00042 #include "Scheduler.h"
00043 #include "maceConfig.h"
00044
00045
00046
00047 static uint64_t getVtid() {
00048 static pthread_mutex_t vtidlock = PTHREAD_MUTEX_INITIALIZER;
00049 static uint64_t tid = 0;
00050 ScopedLock sl(vtidlock);
00051 return tid++;
00052 }
00053
00054
00055 struct FuncArg {
00056 func f;
00057 RunThreadClass* c;
00058 classfunc cf;
00059 void* arg;
00060 uint64_t vtid;
00061 std::string fname;
00062 bool joinThread;
00063 FuncArg(func tf, RunThreadClass* tc, classfunc tcf, void* targ,
00064 uint64_t tvtid, const char* fname, bool join) : f(tf), c(tc), cf(tcf),
00065 arg(targ), vtid(tvtid),
00066 fname(fname),
00067 joinThread(join) {}
00068 };
00069
00070 #ifndef HAVE_GETPPID
00071 static unsigned int getppid() { return 0; }
00072 #endif
00073
00074 void logThread(uint64_t vtid, const std::string& fname, bool ending) {
00075 Log::log("logThread") << fname << " :: pid = " << getpid() << " :: ppid = " << getppid() << " :: v_pthread_id = " << vtid << " :: v_parent_pthread_id = UNKNOWN " << (ending ? "ending" : "starting") << Log::endl;
00076
00077 }
00078
00079 void* threadStart(void* vfa) {
00080 FuncArg* fa = (FuncArg*)vfa;
00081 #ifdef PIP_MESSAGING
00082 ANNOTATE_SET_PATH_ID_STR(NULL, 0, "thread-%s-%d", Util::getAddrString(Util::getMaceAddr()).c_str(), (int)pthread_self());
00083 #endif
00084 Log::traceNewThread(fa->fname);
00085 logThread(fa->vtid, fa->fname);
00086
00087 if(fa->f != NULL) {
00088 (*(fa->f))(fa->arg);
00089 } else {
00090 ASSERT(fa->c != NULL);
00091 ASSERT(fa->cf != NULL);
00092 (fa->c->*(fa->cf))(fa->arg);
00093 }
00094 logThread(fa->vtid, fa->fname, true);
00095
00096 if (fa->joinThread) {
00097 Scheduler::Instance().joinThread(fa->vtid, pthread_self());
00098 }
00099
00100 delete fa;
00101
00102 return 0;
00103 }
00104
00105 void _runNewThread(pthread_t* t, func f, void* arg, pthread_attr_t* attr,
00106 const char* fname, bool joinThread) {
00107 int ret;
00108 FuncArg *fa = new FuncArg(f, NULL, NULL, arg, getVtid(), fname,
00109 joinThread);
00110 if((ret = pthread_create(t, attr, threadStart, fa)) != 0) {
00111 perror("pthread_create");
00112 Log::err() << "Error " << ret << " in creating thread!" << Log::endl;
00113 abort();
00114 }
00115 if (joinThread) {
00116 Scheduler::Instance().shutdownJoinThread(fa->vtid, *t);
00117 }
00118 }
00119
00120 void _runNewThreadClass(pthread_t* t, RunThreadClass* c, classfunc f,
00121 void* arg, pthread_attr_t* attr, const char* fname,
00122 bool joinThread) {
00123 int ret;
00124 FuncArg *fa = new FuncArg(NULL, c, f, arg, getVtid(), fname,
00125 joinThread);
00126 if((ret = pthread_create(t, attr, threadStart, fa)) != 0) {
00127 perror("pthread_create");
00128 Log::err() << "Error " << ret << " in creating thread!" << Log::endl;
00129 abort();
00130 }
00131 if (joinThread) {
00132 Scheduler::Instance().shutdownJoinThread(fa->vtid, *t);
00133 }
00134 }