File: tjthread_code.h

package info (click to toggle)
odin 2.0.5-8
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 9,196 kB
  • sloc: cpp: 62,638; sh: 4,541; makefile: 779
file content (111 lines) | stat: -rw-r--r-- 3,120 bytes parent folder | download | duplicates (7)
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
#include <tjutils/tjthread.h>
#include <tjutils/tjlog.h>


template<typename In, typename Out, typename Local>
void ThreadedLoop<In,Out,Local>::WorkThread::run() {
  Log<ThreadComponent> odinlog("WorkThread","run");
  while(1) {

    process.wait();
    process.reset(); // Reset for next event
    ODINLOG(odinlog,normalDebug) << "catched process signal, cont=" << tloop->cont << STD_endl;
    if(!tloop->cont) break;

    ODINLOG(odinlog,normalDebug) << "processing thread " << begin << "/" << end << STD_endl;

    status=tloop->kernel(*tloop->in_cache, *out_cache, local, begin, end);

    ODINLOG(odinlog,normalDebug) << "signaling finished=" << status << STD_endl;
    finished.signal();

    if(!status) break;
  }
}

//////////////////////////////////////////////////////////////////////////


template<typename In, typename Out, typename Local>
bool ThreadedLoop<In,Out,Local>::init(unsigned int numof_threads, unsigned int loopsize) {
  Log<ThreadComponent> odinlog("ThreadedLoop","init");
  mainbegin=0;
  mainend=loopsize;
#ifndef NO_THREADS
  destroy(); // stop old threads
  ODINLOG(odinlog,normalDebug) << "numof_threads=" << numof_threads << STD_endl;
  if(numof_threads>1) {
    threads.resize(numof_threads-1); // the main thread is also used
    unsigned int onesize=loopsize/numof_threads;
    unsigned int rest=loopsize%numof_threads;
    unsigned int count=0;
    for(unsigned int i=0; i<(numof_threads-1); i++) {
      threads[i]=new WorkThread(this);
      threads[i]->begin=count;
      count+=onesize;
      if(i<rest) count++;
      threads[i]->end=count;
      threads[i]->start();
    }
    mainbegin=count;
    count+=onesize;
    if((numof_threads-1)<rest) count++;
    mainend=count;
  }
#endif
  return true;
}

template<typename In, typename Out, typename Local>
void ThreadedLoop<In,Out,Local>::destroy() {
  Log<ThreadComponent> odinlog("ThreadedLoop","destroy");
#ifndef NO_THREADS
  cont=false; // Stop threads
  for(unsigned int i=0; i<threads.size(); i++) {
    threads[i]->process.signal();
    threads[i]->wait();
    delete threads[i];
  }
  threads.resize(0);
#endif
  }

template<typename In, typename Out, typename Local>
bool ThreadedLoop<In,Out,Local>::execute(const In& in, STD_vector<Out>& outvec) {
  Log<ThreadComponent> odinlog("ThreadedLoop","execute");
#ifdef NO_THREADS
  outvec.resize(1);
  return kernel(in, outvec[0], mainlocal, mainbegin, mainend);
#else

  unsigned int nthreads=threads.size();

  outvec.resize(nthreads+1);

  if(nthreads) {
    in_cache=&in;
    cont=true;

    for(unsigned int i=0; i<nthreads; i++) {
      threads[i]->out_cache=&(outvec[i]);
      threads[i]->status=true;
      threads[i]->process.signal();
    }
  }

  bool result=kernel(in, outvec[nthreads], mainlocal, mainbegin, mainend); // Use mainthread also for kernel

  if(nthreads) {
    for(unsigned int i=0; i<nthreads; i++) {
      threads[i]->finished.wait(); // Wait for result
      threads[i]->finished.reset();
      if(!threads[i]->status) result=false;
    }
    ODINLOG(odinlog,normalDebug) << "finished.wait() done" << STD_endl;
  }

  return result;
#endif
}