ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Linux-AIO/AIO.xs
(Generate patch)

Comparing Linux-AIO/AIO.xs (file contents):
Revision 1.13 by root, Mon Apr 1 20:30:08 2002 UTC vs.
Revision 1.16 by root, Wed May 5 10:13:30 2004 UTC

11 11
12typedef void *InputStream; /* hack, but 5.6.1 is simply toooo old ;) */ 12typedef void *InputStream; /* hack, but 5.6.1 is simply toooo old ;) */
13typedef void *OutputStream; /* hack, but 5.6.1 is simply toooo old ;) */ 13typedef void *OutputStream; /* hack, but 5.6.1 is simply toooo old ;) */
14typedef void *InOutStream; /* hack, but 5.6.1 is simply toooo old ;) */ 14typedef void *InOutStream; /* hack, but 5.6.1 is simply toooo old ;) */
15 15
16#ifndef __NR_pread64
17# define __NR_pread64 __NR_pread
18#endif
19#ifndef __NR_pwrite64
20# define __NR_pwrite64 __NR_pwrite
21#endif
22
16#define STACKSIZE 1024 /* yeah */ 23#define STACKSIZE 1024 /* yeah */
17 24
18enum { REQ_QUIT, REQ_OPEN, REQ_CLOSE, REQ_READ, REQ_WRITE, REQ_STAT, REQ_LSTAT, REQ_FSTAT}; 25enum { REQ_QUIT, REQ_OPEN, REQ_CLOSE, REQ_READ, REQ_WRITE, REQ_STAT, REQ_LSTAT, REQ_FSTAT};
19 26
20typedef struct { 27typedef struct {
22} aio_thread; 29} aio_thread;
23 30
24typedef struct { 31typedef struct {
25 int type; 32 int type;
26 aio_thread *thread; 33 aio_thread *thread;
27
28 SV *savesv;
29 34
30 int fd; 35 int fd;
31 off_t offset; 36 off_t offset;
32 size_t length; 37 size_t length;
33 ssize_t result; 38 ssize_t result;
110 } 115 }
111 116
112 if (length < 0) 117 if (length < 0)
113 croak ("length must not be negative"); 118 croak ("length must not be negative");
114 119
115 New (0, req, 1, aio_cb); 120 Newz (0, req, 1, aio_cb);
116 121
117 if (!req) 122 if (!req)
118 croak ("out of memory during aio_req allocation"); 123 croak ("out of memory during aio_req allocation");
119 124
120 req->type = dowrite ? REQ_WRITE : REQ_READ; 125 req->type = dowrite ? REQ_WRITE : REQ_READ;
145 else 150 else
146 { 151 {
147 int errorno = errno; 152 int errorno = errno;
148 errno = req->errorno; 153 errno = req->errorno;
149 154
150 if (req->savesv)
151 SvREFCNT_dec (req->savesv);
152
153 if (req->type == REQ_READ) 155 if (req->type == REQ_READ)
154 SvCUR_set (req->data, req->dataoffset 156 SvCUR_set (req->data, req->dataoffset
155 + req->result > 0 ? req->result : 0); 157 + req->result > 0 ? req->result : 0);
158
159 if (req->data)
160 SvREFCNT_dec (req->data);
156 161
157 if (req->type == REQ_STAT || req->type == REQ_LSTAT || req->type == REQ_FSTAT) 162 if (req->type == REQ_STAT || req->type == REQ_LSTAT || req->type == REQ_FSTAT)
158 { 163 {
159 PL_laststype = req->type == REQ_LSTAT ? OP_LSTAT : OP_STAT; 164 PL_laststype = req->type == REQ_LSTAT ? OP_LSTAT : OP_STAT;
160 PL_laststatval = req->result; 165 PL_laststatval = req->result;
179 XPUSHs (sv_2mortal (newSViv (req->result))); 184 XPUSHs (sv_2mortal (newSViv (req->result)));
180 PUTBACK; 185 PUTBACK;
181 call_sv (req->callback, G_VOID); 186 call_sv (req->callback, G_VOID);
182 SPAGAIN; 187 SPAGAIN;
183 188
184 SvREFCNT_dec (req->data); 189 if (req->callback)
185 SvREFCNT_dec (req->callback); 190 SvREFCNT_dec (req->callback);
186 191
187 errno = errorno; 192 errno = errorno;
188 nreqs--; 193 nreqs--;
189 count++; 194 count++;
190 } 195 }
205{ 210{
206 aio_thread *thr = thr_arg; 211 aio_thread *thr = thr_arg;
207 aio_req req; 212 aio_req req;
208 int errno; 213 int errno;
209 214
215 /* this is very much x86 and kernel-specific :(:(:( */
210 /* we rely on gcc's ability to create closures. */ 216 /* we rely on gcc's ability to create closures. */
211 _syscall3(int,read,int,fd,char *,buf,size_t,count) 217 _syscall3(int,read,int,fd,char *,buf,size_t,count)
212 _syscall3(int,write,int,fd,char *,buf,size_t,count) 218 _syscall3(int,write,int,fd,char *,buf,size_t,count)
213 219
214 _syscall3(int,open,char *,pathname,int,flags,mode_t,mode) 220 _syscall3(int,open,char *,pathname,int,flags,mode_t,mode)
215 _syscall1(int,close,int,fd) 221 _syscall1(int,close,int,fd)
216 222
217 _syscall4(int,pread,int,fd,char *,buf,size_t,count,off_t,offset) 223 _syscall5(int,pread64,int,fd,char *,buf,size_t,count,unsigned int,offset_lo,unsigned int,offset_hi)
218 _syscall4(int,pwrite,int,fd,char *,buf,size_t,count,off_t,offset) 224 _syscall5(int,pwrite64,int,fd,char *,buf,size_t,count,unsigned int,offset_lo,unsigned int,offset_hi)
219 225
220 _syscall2(int,stat64, const char *, filename, struct stat64 *, buf) 226 _syscall2(int,stat64, const char *, filename, struct stat64 *, buf)
221 _syscall2(int,lstat64, const char *, filename, struct stat64 *, buf) 227 _syscall2(int,lstat64, const char *, filename, struct stat64 *, buf)
222 _syscall2(int,fstat64, int, fd, struct stat64 *, buf) 228 _syscall2(int,fstat64, int, fd, struct stat64 *, buf)
223 229
225 231
226 /* then loop */ 232 /* then loop */
227 while (read (reqpipe[0], (void *)&req, sizeof (req)) == sizeof (req)) 233 while (read (reqpipe[0], (void *)&req, sizeof (req)) == sizeof (req))
228 { 234 {
229 req->thread = thr; 235 req->thread = thr;
230 errno = 0; 236 errno = 0; /* strictly unnecessary */
231 237
232 if (req->type == REQ_READ) 238 if (req->type == REQ_READ)
233 req->result = pread (req->fd, req->dataptr, req->length, req->offset); 239 req->result = pread64 (req->fd, req->dataptr, req->length, req->offset & 0xffffffff, req->offset >> 32);
234 else if (req->type == REQ_WRITE) 240 else if (req->type == REQ_WRITE)
235 req->result = pwrite (req->fd, req->dataptr, req->length, req->offset); 241 req->result = pwrite64(req->fd, req->dataptr, req->length, req->offset & 0xffffffff, req->offset >> 32);
236 else if (req->type == REQ_OPEN) 242 else if (req->type == REQ_OPEN)
237 req->result = open (req->dataptr, req->fd, req->mode); 243 req->result = open (req->dataptr, req->fd, req->mode);
238 else if (req->type == REQ_CLOSE) 244 else if (req->type == REQ_CLOSE)
239 req->result = close (req->fd); 245 req->result = close (req->fd);
240 else if (req->type == REQ_STAT) 246 else if (req->type == REQ_STAT)
241 req->result = stat64 (req->dataptr, req->statdata); 247 req->result = stat64 (req->dataptr, req->statdata);
242 else if (req->type == REQ_LSTAT) 248 else if (req->type == REQ_LSTAT)
243 req->result = lstat64 (req->dataptr, req->statdata); 249 req->result = lstat64 (req->dataptr, req->statdata);
244 else if (req->type == REQ_FSTAT) 250 else if (req->type == REQ_FSTAT)
245 req->result = fstat64 (req->fd, req->statdata); 251 req->result = fstat64 (req->fd, req->statdata);
246 else 252 else
247 { 253 {
248 write (respipe[1], (void *)&req, sizeof (req)); 254 write (respipe[1], (void *)&req, sizeof (req));
249 break; 255 break;
250 } 256 }
291 { 297 {
292 end_thread (); 298 end_thread ();
293 cur--; 299 cur--;
294 } 300 }
295 301
296 poll_cb ();
297 while (started > nthreads) 302 while (started > nthreads)
298 { 303 {
299 sched_yield (); 304 fd_set rfd;
300 fcntl (respipe[0], F_SETFL, 0); 305 FD_ZERO(&rfd);
306 FD_SET(respipe[0], &rfd);
307
308 select (respipe[0] + 1, &rfd, 0, 0, 0);
301 poll_cb (); 309 poll_cb ();
302 fcntl (respipe[0], F_SETFL, O_NONBLOCK);
303 } 310 }
304 311
305void 312void
306aio_open(pathname,flags,mode,callback) 313aio_open(pathname,flags,mode,callback)
307 SV * pathname 314 SV * pathname
310 SV * callback 317 SV * callback
311 PROTOTYPE: $$$$ 318 PROTOTYPE: $$$$
312 CODE: 319 CODE:
313 aio_req req; 320 aio_req req;
314 321
315 New (0, req, 1, aio_cb); 322 Newz (0, req, 1, aio_cb);
316 323
317 if (!req) 324 if (!req)
318 croak ("out of memory during aio_req allocation"); 325 croak ("out of memory during aio_req allocation");
319 326
320 req->type = REQ_OPEN; 327 req->type = REQ_OPEN;
321 req->savesv = newSVsv (pathname); 328 req->data = newSVsv (pathname);
322 req->dataptr = SvPV_nolen (req->savesv); 329 req->dataptr = SvPV_nolen (req->data);
323 req->fd = flags; 330 req->fd = flags;
324 req->mode = mode; 331 req->mode = mode;
325 req->callback = SvREFCNT_inc (callback); 332 req->callback = SvREFCNT_inc (callback);
326 333
327 send_req (req); 334 send_req (req);
328 335
329void 336void
330aio_close(fh,callback) 337aio_close(fh,callback)
331 InputStream fh 338 InputStream fh
332 SV * callback 339 SV * callback
333 PROTOTYPE: $ 340 PROTOTYPE: $$
334 CODE: 341 CODE:
335 aio_req req; 342 aio_req req;
336 343
337 New (0, req, 1, aio_cb); 344 Newz (0, req, 1, aio_cb);
338 345
339 if (!req) 346 if (!req)
340 croak ("out of memory during aio_req allocation"); 347 croak ("out of memory during aio_req allocation");
341 348
342 req->type = REQ_CLOSE; 349 req->type = REQ_CLOSE;
377 ALIAS: 384 ALIAS:
378 aio_lstat = 1 385 aio_lstat = 1
379 CODE: 386 CODE:
380 aio_req req; 387 aio_req req;
381 388
382 New (0, req, 1, aio_cb); 389 Newz (0, req, 1, aio_cb);
383 390
384 if (!req) 391 if (!req)
385 croak ("out of memory during aio_req allocation"); 392 croak ("out of memory during aio_req allocation");
386 393
387 New (0, req->statdata, 1, struct stat64); 394 New (0, req->statdata, 1, struct stat64);
390 croak ("out of memory during aio_req->statdata allocation"); 397 croak ("out of memory during aio_req->statdata allocation");
391 398
392 if (SvPOK (fh_or_path)) 399 if (SvPOK (fh_or_path))
393 { 400 {
394 req->type = ix ? REQ_LSTAT : REQ_STAT; 401 req->type = ix ? REQ_LSTAT : REQ_STAT;
395 req->savesv = newSVsv (fh_or_path); 402 req->data = newSVsv (fh_or_path);
396 req->dataptr = SvPV_nolen (req->savesv); 403 req->dataptr = SvPV_nolen (req->data);
397 } 404 }
398 else 405 else
399 { 406 {
400 req->type = REQ_FSTAT; 407 req->type = REQ_FSTAT;
401 req->fd = PerlIO_fileno (IoIFP (sv_2io (fh_or_path))); 408 req->fd = PerlIO_fileno (IoIFP (sv_2io (fh_or_path)));

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines