Statistics
| Branch: | Revision:

root / synthbench / bonnie++ / .svn / text-base / forkit.cpp.svn-base @ 0:839f52ef7657

History | View | Annotate | Download (3.6 kB)

1

    
2
#ifdef OS2
3
#define INCL_DOSPROCESS
4
#else
5
#include <unistd.h>
6
#include <time.h>
7
#include <stdlib.h>
8
#include <sys/types.h>
9
#include <sys/wait.h>
10
#endif
11

    
12
#include "forkit.h"
13

    
14

    
15
Fork::Fork()
16
 : m_read(-1)
17
 , m_write(-1)
18
 , m_numThreads(0)
19
{
20
}
21

    
22
#ifdef OS2
23
// for the benefit of this function and the new Fork class it may create
24
// the Fork class must do nothing of note in it's constructor or it's
25
// go() member function.
26
VOID APIENTRY thread_func(ULONG param)
27
{
28
  THREAD_DATA *td = (THREAD_DATA *)param;
29
  td->f = new Fork;
30
  td->f->startit(td);
31
}
32
#endif
33

    
34
void Fork::startit(THREAD_DATA *td)
35
{
36
  m_read = td->child_read;
37
  m_write = td->child_write;
38
  td->func(this, td->param, td->threadNum);
39
  delete td->f; // delete ourself if td->f is not NULL
40
  delete td;
41
  exit(0);
42
}
43

    
44
void Fork::go(FUNCTION func, PVOID param, int num)
45
{
46
  m_numThreads = num;
47
  FILE_TYPE control[2];
48
  FILE_TYPE feedback[2];
49
  if (pipe(feedback) || pipe(control))
50
  {
51
    fprintf(stderr, "Can't open pipes.\n");
52
    exit(1);
53
  }
54
#ifndef OS2
55
  m_readPoll.events = POLLIN | POLLERR | POLLHUP | POLLNVAL;
56
  m_writePoll.events = POLLOUT | POLLERR | POLLHUP | POLLNVAL;
57
#endif
58

    
59
  THREAD_DATA *td = new THREAD_DATA;
60
  td->child_read = control[0];
61
  td->child_write = feedback[1];
62
  td->f = NULL;
63
  td->param = param;
64
  td->func = func;
65
  for(int i = 0; i < num; i++)
66
  {
67
#ifdef OS2
68
    THREAD_DATA *tmp = new THREAD_DATA;
69
    memcpy(tmp, td, sizeof(THREAD_DATA));
70
#endif
71
    td->threadNum = i;
72
#ifdef OS2
73
    // yes I know I am casting a pointer to an unsigned long
74
    // it's the way you're supposed to do things in OS/2
75
    TID id = 0;
76
    if(DosCreateThread(&id, thread_func, ULONG(td), CREATE_READY, 32*1024))
77
    {
78
      fprintf(stderr, "Can't create a thread.\n");
79
      exit(1);
80
    }
81
#else
82
    int p = fork();
83
    if(p == -1)
84
    {
85
      fprintf(stderr, "Can't fork.\n");
86
      exit(1);
87
    }
88
    if(p == 0) // child
89
    {
90
      m_readPoll.fd = td->child_read;
91
      m_writePoll.fd = td->child_write;
92
      file_close(control[1]);
93
      file_close(feedback[0]);
94
      srand(getpid() ^ time(NULL));
95
      startit(td);
96
    }
97
#endif
98
  }
99
  // now we're in the parent thread/process
100
  m_write = control[1];
101
  m_read = feedback[0];
102
#ifndef OS2
103
  m_readPoll.fd = m_read;
104
  m_writePoll.fd = m_write;
105
  file_close(control[0]);
106
  file_close(feedback[1]);
107
#endif
108
}
109

    
110
int Fork::wait()
111
{
112
#ifdef OS2
113
  TID status = 0;
114
  if(DosWaitThread(&status, DCWW_WAIT))
115
  {
116
    fprintf(stderr, "Can't wait for thread.\n");
117
    return 1;
118
  }
119
#else
120
  int status = 0;
121
  if(::wait(&status) == -1)
122
  {
123
    fprintf(stderr, "Can't wait for thread.\n");
124
    return 1;
125
  }
126
#endif
127
  return 0;
128
}
129

    
130
int Fork::Read(PVOID buf, int size, int timeout)
131
{
132
#ifndef OS2
133
  if(timeout)
134
  {
135
    int rc = poll(&m_readPoll, 1, timeout * 1000);
136
    if(rc < 0)
137
    {
138
      fprintf(stderr, "Can't poll.\n");
139
      return -1;
140
    }
141
    if(!rc)
142
      return 0;
143
  }
144
#endif
145
#ifdef OS2
146
  unsigned long actual;
147
  int rc = DosRead(m_read, buf, size, &actual);
148
  if(rc || actual != size)
149
#else
150
  if(size != read(m_read, buf, size) )
151
#endif
152
  {
153
    fprintf(stderr, "Can't read data from IPC pipe.\n");
154
    return -1;
155
  }
156
  return size;
157
}
158

    
159
int Fork::Write(PVOID buf, int size, int timeout)
160
{
161
#ifndef OS2
162
  if(timeout)
163
  {
164
    int rc = poll(&m_writePoll, 1, timeout * 1000);
165
    if(rc < 0)
166
    {
167
      fprintf(stderr, "Can't poll for write.\n");
168
      return -1;
169
    }
170
    if(!rc)
171
      return 0;
172
  }
173
#endif
174
#ifdef OS2
175
  unsigned long actual;
176
  int rc = DosWrite(m_write, buf, size, &actual);
177
  if(rc || actual != size)
178
#else
179
  if(size != write(m_write, buf, size))
180
#endif
181
  {
182
    fprintf(stderr, "Can't write data to IPC pipe.\n");
183
    return -1;
184
  }
185
  return size;
186
}
187