ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Linux-AIO/AIO.xs
Revision: 1.4
Committed: Tue Aug 14 14:56:22 2001 UTC (22 years, 9 months ago) by root
Branch: MAIN
Changes since 1.3: +3 -2 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 #include "EXTERN.h"
2     #include "perl.h"
3     #include "XSUB.h"
4    
5     #include <sys/types.h>
6     #include <unistd.h>
7     #include <sched.h>
8    
9     #define STACKSIZE 128 /* yeah */
10    
11 root 1.2 #define REQ_QUIT 0
12 root 1.1 #define REQ_READ 1
13     #define REQ_WRITE 2
14    
15     typedef struct {
16     char stack[STACKSIZE];
17     } aio_thread;
18    
19     typedef struct {
20     int type;
21     aio_thread *thread;
22    
23     /* read/write */
24     int fd;
25     off_t offset;
26     size_t length;
27 root 1.2 ssize_t result;
28 root 1.1 int errorno;
29    
30     SV *data;
31     void *dataptr;
32 root 1.2 STRLEN dataoffset;
33 root 1.1 } aio_cb;
34    
35     typedef aio_cb *aio_req;
36    
37     static int started;
38     static int reqpipe[2], respipe[2];
39    
40 root 1.2 static int aio_proc(void *arg);
41    
42 root 1.1 static void
43     start_thread(void)
44     {
45 root 1.2 aio_thread *thr;
46    
47     New (0, thr, 1, aio_thread);
48    
49     if (clone (aio_proc,
50     &(thr->stack[STACKSIZE]),
51     CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND,
52     thr) >= 0)
53     started++;
54     else
55     Safefree (thr);
56 root 1.1 }
57    
58     static void
59     end_thread(void)
60     {
61     aio_req req = 0;
62     write (reqpipe[1], &req, sizeof (aio_req));
63 root 1.2 started--;
64     }
65    
66     static void
67     set_errno(int errorno)
68     {
69     errno = errorno;
70     }
71    
72     #undef errno
73     #include <asm/unistd.h>
74    
75     static int
76     aio_proc(void *thr_arg)
77     {
78     aio_thread *thr = thr_arg;
79     int sig;
80     int errno;
81     aio_req req;
82    
83     /* we rely on gcc's ability to create closures. */
84     _syscall3(int,lseek,int,fd,off_t,offset,int,whence);
85     _syscall3(int,read,int,fd,char *,buf,off_t,count);
86     _syscall3(int,write,int,fd,char *,buf,off_t,count);
87    
88     /* first get rid of any signals */
89     for (sig = 1; sig < _NSIG; sig++)
90 root 1.4 signal (sig, SIG_IGN);
91    
92     signal (SIGTERM, SIG_DFL);
93 root 1.2
94     /* then loop */
95     while (read (reqpipe[0], (void *)&req, sizeof (req)) == sizeof (req))
96     {
97     req->thread = thr;
98    
99     if (req->type == REQ_READ || req->type == REQ_WRITE)
100     {
101     errno = 0;
102    
103     if (lseek (req->fd, req->offset, SEEK_SET) == req->offset)
104     {
105     if (req->type == REQ_READ)
106     req->result = read (req->fd, req->dataptr, req->length);
107     else
108     req->result = write(req->fd, req->dataptr, req->length);
109     }
110    
111     req->errorno = errno;
112     }
113     else
114     {
115     write (respipe[1], (void *)&req, sizeof (req));
116     break;
117     }
118    
119     write (respipe[1], (void *)&req, sizeof (req));
120     }
121    
122     return 0;
123 root 1.1 }
124    
125     MODULE = Linux::AIO PACKAGE = Linux::AIO
126    
127     BOOT:
128     {
129     if (pipe (reqpipe) || pipe (respipe))
130     croak ("unable to initialize request or result pipe");
131     }
132    
133     void
134     min_parallel(nthreads)
135     int nthreads
136     CODE:
137     while (nthreads > started)
138     start_thread ();
139    
140     void
141     max_parallel(nthreads)
142     int nthreads
143     CODE:
144     while (started > nthreads)
145     end_thread ();
146    
147     void
148     read(fh,offset,length,data,dataoffset,callback)
149 root 1.3 ALIAS:
150     write = 1
151 root 1.1 CODE: