fifo.c
上传用户:xiejiait
上传日期:2007-01-06
资源大小:881k
文件大小:16k
源码类别:

SCSI/ASPI

开发平台:

MultiPlatform

  1. /* @(#)fifo.c 1.21 99/12/29 Copyright 1989,1997 J. Schilling */
  2. #ifndef lint
  3. static char sccsid[] =
  4. "@(#)fifo.c 1.21 99/12/29 Copyright 1989,1997 J. Schilling";
  5. #endif
  6. /*
  7.  * A "fifo" that uses shared memory between two processes
  8.  *
  9.  * The actual code is a mixture of borrowed code from star's fifo.c
  10.  * and a proposal from Finn Arne Gangstad <finnag@guardian.no>
  11.  * who had the idea to use a ring buffer to handle average size chunks.
  12.  *
  13.  * Copyright (c) 1989,1997 J. Schilling
  14.  */
  15. /*
  16.  * This program is free software; you can redistribute it and/or modify
  17.  * it under the terms of the GNU General Public License as published by
  18.  * the Free Software Foundation; either version 2, or (at your option)
  19.  * any later version.
  20.  *
  21.  * This program is distributed in the hope that it will be useful,
  22.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  23.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  24.  * GNU General Public License for more details.
  25.  *
  26.  * You should have received a copy of the GNU General Public License
  27.  * along with this program; see the file COPYING.  If not, write to
  28.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  29.  */
  30. #define DEBUG
  31. /*#define XDEBUG*/
  32. #include <mconfig.h>
  33. #if !defined(HAVE_SMMAP) && !defined(HAVE_USGSHM) && !defined(HAVE_DOSALLOCSHAREDMEM)
  34. #undef FIFO /* We cannot have a FIFO on this platform */
  35. #endif
  36. #ifdef FIFO
  37. #if !defined(USE_MMAP) && !defined(USE_USGSHM)
  38. #define USE_MMAP
  39. #endif
  40. #ifndef HAVE_SMMAP
  41. # undef USE_MMAP
  42. # define USE_USGSHM /* now SYSV shared memory is the default*/
  43. #endif
  44. #ifdef USE_MMAP /* Only want to have one implementation */
  45. # undef USE_USGSHM /* mmap() is preferred */
  46. #endif
  47. #ifdef HAVE_DOSALLOCSHAREDMEM /* This is for OS/2 */
  48. # undef USE_MMAP
  49. # undef USE_USGSHM
  50. # define USE_OS2SHM
  51. #endif
  52. #include <fctldefs.h>
  53. #include <sys/types.h>
  54. #if defined(HAVE_SMMAP) && defined(USE_MMAP)
  55. #include <sys/mman.h>
  56. #endif
  57. #include <stdio.h>
  58. #include <stdxlib.h>
  59. #include <unixstd.h>
  60. #include <waitdefs.h>
  61. #include <utypes.h>
  62. #include <standard.h>
  63. #include <errno.h>
  64. #include <signal.h>
  65. #include <libport.h>
  66. #include "cdrecord.h"
  67. #ifdef DEBUG
  68. #ifdef XDEBUG
  69. FILE *ef;
  70. #define USDEBUG1 if (debug) {if(s == owner_reader)fprintf(ef, "r");else fprintf(ef, "w");fflush(ef);}
  71. #define USDEBUG2 if (debug) {if(s == owner_reader)fprintf(ef, "R");else fprintf(ef, "W");fflush(ef);}
  72. #else
  73. #define USDEBUG1
  74. #define USDEBUG2
  75. #endif
  76. #define EDEBUG(a) if (debug) error a
  77. #else
  78. #define EDEBUG(a)
  79. #define USDEBUG1
  80. #define USDEBUG2
  81. #endif
  82. #define palign(x, a) (((char *)(x)) + ((a) - 1 - (((unsigned)((x)-1))%(a))))
  83. typedef enum faio_owner {
  84. owner_none,
  85. owner_reader,
  86. owner_writer,
  87. owner_faio
  88. } fowner_t;
  89. char *onames[] = {
  90. "none",
  91. "reader",
  92. "writer",
  93. "faio"
  94. };
  95. typedef struct faio {
  96. int len;
  97. volatile fowner_t owner;
  98. short fd;
  99. short saved_errno;
  100. char *bufp;
  101. } faio_t;
  102. struct faio_stats {
  103. long puts;
  104. long gets;
  105. long empty;
  106. long full;
  107. long done;
  108. long cont_low;
  109. } *sp;
  110. #define MIN_BUFFERS 3
  111. #define MSECS 1000
  112. #define SECS (1000*MSECS)
  113. /*
  114.  * Note: WRITER_MAXWAIT & READER_MAXWAIT need to be greater than the SCSI
  115.  * timeout for commands that write to the media. This is currently 200s
  116.  * if we are in SAO mode.
  117.  */
  118. /* microsecond delay between each buffer-ready probe by writing process */
  119. #define WRITER_DELAY (20*MSECS)
  120. #define WRITER_MAXWAIT (240*SECS) /* 240 seconds max wait for data */
  121. /* microsecond delay between each buffer-ready probe by reading process */
  122. #define READER_DELAY (80*MSECS)
  123. #define READER_MAXWAIT (240*SECS) /* 240 seconds max wait for reader */
  124. LOCAL char *buf;
  125. LOCAL char *bufbase;
  126. LOCAL char *bufend;
  127. LOCAL long buflen;
  128. extern int debug;
  129. extern int lverbose;
  130. EXPORT void init_fifo __PR((long));
  131. #ifdef USE_MMAP
  132. LOCAL char* mkshare __PR((int size));
  133. #endif
  134. #ifdef USE_USGSHM
  135. LOCAL char* mkshm __PR((int size));
  136. #endif
  137. #ifdef USE_OS2SHM
  138. LOCAL char* mkos2shm __PR((int size));
  139. #endif
  140. EXPORT BOOL init_faio __PR((int tracks, track_t *track, int));
  141. EXPORT BOOL await_faio __PR((void));
  142. EXPORT void kill_faio __PR((void));
  143. EXPORT int wait_faio __PR((void));
  144. LOCAL void faio_reader __PR((int tracks, track_t *track));
  145. LOCAL void faio_read_track __PR((track_t *trackp));
  146. LOCAL void faio_wait_on_buffer __PR((faio_t *f, fowner_t s,
  147.   unsigned long delay,
  148.   unsigned long max_wait));
  149. LOCAL int faio_read_segment __PR((int fd, faio_t *f, int len));
  150. LOCAL faio_t *faio_ref __PR((int n));
  151. EXPORT int faio_read_buf __PR((int f, char *bp, int size));
  152. EXPORT int faio_get_buf __PR((int f, char **bpp, int size));
  153. EXPORT void fifo_stats __PR((void));
  154. EXPORT int fifo_percent __PR((BOOL addone));
  155. EXPORT void
  156. init_fifo(fs)
  157. long fs;
  158. {
  159. int pagesize;
  160. if (fs == 0L)
  161. return;
  162. #ifdef _SC_PAGESIZE
  163. pagesize = sysconf(_SC_PAGESIZE);
  164. #else
  165. pagesize = getpagesize();
  166. #endif
  167. buflen = roundup(fs, pagesize) + pagesize;
  168. EDEBUG(("fs: %ld buflen: %ldn", fs, buflen));
  169. #if defined(USE_MMAP)
  170. buf = mkshare(buflen);
  171. #endif
  172. #if defined(USE_USGSHM)
  173. buf = mkshm(buflen);
  174. #endif
  175. #if defined(USE_OS2SHM)
  176. buf = mkos2shm(buflen);
  177. #endif
  178. bufbase = buf;
  179. bufend = buf + buflen;
  180. EDEBUG(("buf: %X bufend: %X, buflen: %ldn", buf, bufend, buflen));
  181. buf = palign(buf, pagesize);
  182. buflen -= buf - bufbase;
  183. EDEBUG(("buf: %X bufend: %X, buflen: %ld (align %ld)n", buf, bufend, buflen, buf - bufbase));
  184. /*
  185.  * Dirty the whole buffer. This can die with various signals if
  186.  * we're trying to lock too much memory
  187.  */
  188. fillbytes(buf, buflen, '');
  189. #ifdef XDEBUG
  190. if (debug)
  191. ef = fopen("/tmp/ef", "w");
  192. #endif
  193. }
  194. #ifdef USE_MMAP
  195. LOCAL char *
  196. mkshare(size)
  197. int size;
  198. {
  199. int f;
  200. char *addr;
  201. #ifdef MAP_ANONYMOUS /* HP/UX */
  202. f = -1;
  203. addr = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, f, 0);
  204. #else
  205. if ((f = open("/dev/zero", O_RDWR)) < 0)
  206. comerr("Cannot open '/dev/zero'.n");
  207. addr = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, f, 0);
  208. #endif
  209. if (addr == (char *)-1)
  210. comerr("Cannot get mmap for %d Bytes on /dev/zero.n", size);
  211. close(f);
  212. if (debug) errmsgno(EX_BAD, "shared memory segment attached: %xn", addr);
  213. return (addr);
  214. }
  215. #endif
  216. #ifdef USE_USGSHM
  217. #include <sys/ipc.h>
  218. #include <sys/shm.h>
  219. LOCAL char *
  220. mkshm(size)
  221. int size;
  222. {
  223. int id;
  224. char *addr;
  225. /*
  226.  * Unfortunately, a declaration of shmat() is missing in old
  227.  * implementations such as AT&T SVr0 and SunOS.
  228.  * We cannot add this definition here because the return-type
  229.  * changed on newer systems.
  230.  *
  231.  * We will get a warning like this:
  232.  *
  233.  * warning: assignment of pointer from integer lacks a cast
  234.  * or
  235.  * warning: illegal combination of pointer and integer, op =
  236.  */
  237. /* extern char *shmat();*/
  238. if ((id = shmget(IPC_PRIVATE, size, IPC_CREAT|0600)) == -1)
  239. comerr("shmget failedn");
  240. if (debug) errmsgno(EX_BAD, "shared memory segment allocated: %dn", id);
  241. if ((addr = shmat(id, (char *)0, 0600)) == (char *)-1)
  242. comerr("shmat failedn");
  243. if (debug) errmsgno(EX_BAD, "shared memory segment attached: %xn", addr);
  244. if (shmctl(id, IPC_RMID, 0) < 0)
  245. comerr("shmctl failed to detach shared memory segmentn");
  246. #ifdef SHM_LOCK
  247. /*
  248.  * Although SHM_LOCK is standard, it seems that all versions of AIX
  249.  * ommit this definition.
  250.  */
  251. if (shmctl(id, SHM_LOCK, 0) < 0)
  252. comerr("shmctl failed to lock shared memory segmentn");
  253. #endif
  254. return (addr);
  255. }
  256. #endif
  257. #ifdef USE_OS2SHM
  258. LOCAL char *
  259. mkos2shm(size)
  260. int size;
  261. {
  262. char *addr;
  263. /*
  264.  * The OS/2 implementation of shm (using shm.dll) limits the size of one shared
  265.  * memory segment to 0x3fa000 (aprox. 4MBytes). Using OS/2 native API we have
  266.  * no such restriction so I decided to use it allowing fifos of arbitrary size.
  267.          */
  268. if(DosAllocSharedMem(&addr,NULL,size,0X100L | 0x1L | 0x2L | 0x10L))
  269. comerr("DosAllocSharedMem() failedn");
  270. if (debug)
  271. errmsgno(EX_BAD, "shared memory allocated at address: %xn", addr);
  272. return (addr);
  273. }
  274. #endif
  275. LOCAL int faio_buffers;
  276. LOCAL int faio_buf_size;
  277. LOCAL int buf_idx;
  278. LOCAL pid_t faio_pid;
  279. LOCAL BOOL faio_didwait;
  280. /*#define faio_ref(n) (&((faio_t *)buf)[n])*/
  281. EXPORT BOOL
  282. init_faio(tracks, track, bufsize)
  283. int tracks;
  284. track_t *track;
  285. int bufsize;
  286. {
  287. int n;
  288. faio_t *f;
  289. int pagesize;
  290. char *base;
  291. if (buflen == 0L)
  292. return (FALSE);
  293. #ifdef _SC_PAGESIZE
  294. pagesize = sysconf(_SC_PAGESIZE);
  295. #else
  296. pagesize = getpagesize();
  297. #endif
  298. faio_buf_size = bufsize;
  299. f = (faio_t *)buf;
  300. /*
  301.  * Compute space for buffer headers.
  302.  * Round bufsize up to pagesize to make each FIFO segment
  303.  * properly page aligned.
  304.  */
  305. bufsize = roundup(bufsize, pagesize);
  306. faio_buffers = (buflen - sizeof(*sp)) / bufsize;
  307. EDEBUG(("bufsize: %d buffers: %d hdrsize %dn", bufsize, faio_buffers, faio_buffers * sizeof(struct faio)));
  308. /*
  309.  * Reduce buffer space by header space.
  310.  */
  311. n = sizeof(*sp) + faio_buffers * sizeof(struct faio);
  312. n = roundup(n, pagesize);
  313. faio_buffers = (buflen-n) / bufsize;
  314. EDEBUG(("bufsize: %d buffers: %d hdrsize %dn", bufsize, faio_buffers, faio_buffers * sizeof(struct faio)));
  315. if (faio_buffers < MIN_BUFFERS) {
  316. errmsgno(EX_BAD,
  317. "write-buffer too small, minimum is %dk. Disabling.n",
  318. MIN_BUFFERS*bufsize/1024);
  319. return (FALSE);
  320. }
  321. if (debug)
  322. printf("Using %d buffers of %d bytes.n", faio_buffers, faio_buf_size);
  323. f = (faio_t *)buf;
  324. base = buf + roundup(sizeof(*sp) + faio_buffers * sizeof(struct faio),
  325. pagesize);
  326. for (n = 0; n < faio_buffers; n++, f++, base += bufsize) {
  327. /* Give all the buffers to the reader process */
  328. f->owner = owner_writer;
  329. f->bufp = base;
  330. f->fd = -1;
  331. }
  332. sp = (struct faio_stats *)f; /* point past headers */
  333. sp->gets = sp->puts = sp->done = 0L;
  334. faio_pid = fork();
  335. if (faio_pid < 0)
  336. comerr("fork(2) failed");
  337. if (faio_pid == 0) {
  338. /* child process */
  339. raisepri(1); /* almost max priority */
  340. #ifdef USE_OS2SHM
  341. DosGetSharedMem(buf,3); /* PAG_READ|PAG_WRITE */
  342. #endif
  343. /* Ignoring SIGALRM cures the SCO usleep() bug */
  344. /* signal(SIGALRM, SIG_IGN);*/
  345. faio_reader(tracks, track);
  346. /* NOTREACHED */
  347. } else {
  348. faio_didwait = FALSE;
  349. /* close all file-descriptors that only the child will use */
  350. for (n = 1; n <= tracks; n++)
  351. close(track[n].f);
  352. }
  353. return (TRUE);
  354. }
  355. EXPORT BOOL
  356. await_faio()
  357. {
  358. int n;
  359. int lastfd = -1;
  360. faio_t *f;
  361. /*
  362.  * Wait until the reader is active and has filled the buffer.
  363.  */
  364. if (lverbose || debug) {
  365. printf("Waiting for reader process to fill input buffer ... ");
  366. flush();
  367. }
  368. faio_wait_on_buffer(faio_ref(faio_buffers - 1), owner_reader,
  369.     500*MSECS, 0);
  370. if (lverbose || debug)
  371. printf("input buffer ready.n");
  372. sp->empty = sp->full = 0L; /* set correct stat state */
  373. sp->cont_low = faio_buffers; /* set cont to max value  */
  374. f = faio_ref(0);
  375. for (n = 0; n < faio_buffers; n++, f++) {
  376. if (f->fd != lastfd &&
  377. f->fd == STDIN_FILENO && f->len == 0) {
  378. errmsgno(EX_BAD, "Premature EOF on stdin.n");
  379. kill(faio_pid, SIGKILL);
  380. return (FALSE);
  381. }
  382. lastfd = f->fd;
  383. }
  384. return (TRUE);
  385. }
  386. EXPORT void
  387. kill_faio()
  388. {
  389. if (faio_pid > 0)
  390. kill(faio_pid, SIGKILL);
  391. }
  392. EXPORT int
  393. wait_faio()
  394. {
  395. if (faio_pid > 0 && !faio_didwait)
  396. return (wait(0));
  397. faio_didwait = TRUE;
  398. return (0);
  399. }
  400. LOCAL void
  401. faio_reader(tracks, track)
  402. int tracks;
  403. track_t *track;
  404. {
  405. /* This function should not return, but _exit. */
  406. int trackno;
  407. if (debug)
  408. printf("nfaio_reader startingn");
  409. for (trackno = 1; trackno <= tracks; trackno++) {
  410. if (debug)
  411. printf("nfaio_reader reading track %dn", trackno);
  412. faio_read_track(&track[trackno]);
  413. }
  414. sp->done++;
  415. if (debug)
  416. printf("nfaio_reader all tracks read, exitingn");
  417. /* Prevent hang if buffer is larger than all the tracks combined */
  418. if (sp->gets == 0)
  419. faio_ref(faio_buffers - 1)->owner = owner_reader;
  420. #ifdef USE_OS2SHM
  421. DosFreeMem(buf);
  422. sleep(30000); /* XXX If calling _exit() here the parent process seems to be blocked */
  423. /* XXX This should be fixed soon */
  424. #endif
  425. if (debug)
  426. error("nfaio_reader _exit(0)n");
  427. _exit(0);
  428. }
  429. #ifndef faio_ref
  430. LOCAL faio_t *
  431. faio_ref(n)
  432. int n;
  433. {
  434. return (&((faio_t *)buf)[n]);
  435. }
  436. #endif
  437. LOCAL void
  438. faio_read_track(trackp)
  439. track_t *trackp;
  440. {
  441. int fd = trackp->f;
  442. int bytespt = trackp->secsize * trackp->secspt;
  443. int l;
  444. long tracksize = trackp->tracksize;
  445. long bytes_read = 0L;
  446. long bytes_to_read;
  447. if (bytespt > faio_buf_size) {
  448. comerrno(EX_BAD,
  449. "faio_read_track fatal: secsize %d secspt %d, bytespt(%d) > %d !!n",
  450.  trackp->secsize, trackp->secspt, bytespt,
  451.  faio_buf_size);
  452. }
  453. do {
  454. bytes_to_read = bytespt;
  455. if (tracksize > 0) {
  456. bytes_to_read = tracksize - bytes_read;
  457. if (bytes_to_read > bytespt)
  458. bytes_to_read = bytespt;
  459. }
  460. l = faio_read_segment(fd, faio_ref(buf_idx), bytes_to_read);
  461. if (++buf_idx >= faio_buffers)
  462. buf_idx = 0;
  463. if (l <= 0)
  464. break;
  465. bytes_read += l;
  466. } while (tracksize < 0 || bytes_read < tracksize);
  467. close(fd); /* Don't keep files open longer than neccesary */
  468. }
  469. LOCAL void
  470. faio_wait_on_buffer(f, s, delay, max_wait)
  471. faio_t *f;
  472. fowner_t s;
  473. unsigned long delay;
  474. unsigned long max_wait;
  475. {
  476. unsigned long max_loops;
  477. if (f->owner == s)
  478. return; /* return immediately if the buffer is ours */
  479. if (s == owner_reader)
  480. sp->empty++;
  481. else
  482. sp->full++;
  483. max_loops = max_wait / delay + 1;
  484. while (max_wait == 0 || max_loops--) {
  485. USDEBUG1;
  486. usleep(delay);
  487. USDEBUG2;
  488. if (f->owner == s)
  489. return;
  490. }
  491. if (debug) {
  492. errmsgno(EX_BAD,
  493. "%lu microseconds passed waiting for %d current: %d idx: %dn",
  494. max_wait, s, f->owner, (f - faio_ref(0))/sizeof(*f));
  495. }
  496. comerrno(EX_BAD, "faio_wait_on_buffer for %s timed out.n",
  497. (s > owner_faio || s < owner_none) ? "bad_owner" : onames[s]);
  498. }
  499. LOCAL int
  500. faio_read_segment(fd, f, len)
  501. int fd;
  502. faio_t *f;
  503. int len;
  504. {
  505. int l;
  506. faio_wait_on_buffer(f, owner_writer, WRITER_DELAY, WRITER_MAXWAIT);
  507. f->fd = fd;
  508. l = read_buf(fd, f->bufp, len);
  509. f->len = l;
  510. f->saved_errno = errno;
  511. f->owner = owner_reader;
  512. sp->puts++;
  513. return l;
  514. }
  515. EXPORT int
  516. faio_read_buf(fd, bp, size)
  517. int fd;
  518. char *bp;
  519. int size;
  520. {
  521. char *bufp;
  522. int len = faio_get_buf(fd, &bufp, size);
  523. if (len > 0) {
  524. movebytes(bufp, bp, len);
  525. }
  526. return len;
  527. }
  528. EXPORT int
  529. faio_get_buf(fd, bpp, size)
  530. int fd;
  531. char **bpp;
  532. int size;
  533. {
  534. faio_t *f;
  535. int len;
  536. again:
  537. f = faio_ref(buf_idx);
  538. if (f->owner == owner_faio) {
  539. f->owner = owner_writer;
  540. if (++buf_idx >= faio_buffers)
  541. buf_idx = 0;
  542. f = faio_ref(buf_idx);
  543. }
  544. if ((sp->puts - sp->gets) < sp->cont_low && sp->done == 0) {
  545. EDEBUG(("gets: %d puts: %d cont: %d low: %dn", sp->gets, sp->puts, sp->puts - sp->gets, sp->cont_low));
  546. sp->cont_low = sp->puts - sp->gets;
  547. }
  548. faio_wait_on_buffer(f, owner_reader, READER_DELAY, READER_MAXWAIT);
  549. len = f->len;
  550. if (f->fd != fd) {
  551. if (f->len == 0) {
  552. /*
  553.  * If the tracksize for this track was known, and
  554.  * the tracksize is 0 mod bytespt, this happens.
  555.  */
  556. goto again;
  557. }
  558. comerrno(EX_BAD,
  559. "faio_get_buf fatal: fd=%d, f->fd=%d, f->len=%d f->errno=%dn",
  560. fd, f->fd, f->len, f->saved_errno);
  561. }
  562. if (size < len) {
  563. comerrno(EX_BAD,
  564. "unexpected short read-attempt in faio_get_buf. size = %d, len = %dn",
  565. size, len);
  566. }
  567. if (len < 0)
  568. errno = f->saved_errno;
  569. sp->gets++;
  570. *bpp = f->bufp;
  571. f->owner = owner_faio;
  572. return len;
  573. }
  574. EXPORT void
  575. fifo_stats()
  576. {
  577. if (sp == NULL) /* We might not use a FIFO */
  578. return;
  579. errmsgno(EX_BAD, "fifo had %ld puts and %ld gets.n",
  580. sp->puts, sp->gets);
  581. errmsgno(EX_BAD, "fifo was %ld times empty and %ld times full, min fill was %ld%%.n",
  582. sp->empty, sp->full, (100L*sp->cont_low)/faio_buffers);
  583. }
  584. EXPORT int
  585. fifo_percent(addone)
  586. BOOL addone;
  587. {
  588. int percent;
  589. if (buflen == 0L)
  590. return (-1);
  591. if (sp->done)
  592. return (100);
  593. percent = (100*(sp->puts + 1 - sp->gets)/faio_buffers);
  594. if (percent > 100)
  595. return (100);
  596. return (percent);
  597. }
  598. #else /* FIFO */
  599. #include <standard.h>
  600. #include <sys/types.h>
  601. #include <utypes.h>
  602. #include "cdrecord.h"
  603. EXPORT void init_fifo __PR((long));
  604. EXPORT BOOL init_faio __PR((int tracks, track_t *track, int));
  605. EXPORT BOOL await_faio __PR((void));
  606. EXPORT void kill_faio __PR((void));
  607. EXPORT int wait_faio __PR((void));
  608. EXPORT int faio_read_buf __PR((int f, char *bp, int size));
  609. EXPORT int faio_get_buf __PR((int f, char **bpp, int size));
  610. EXPORT void fifo_stats __PR((void));
  611. EXPORT int fifo_percent __PR((BOOL addone));
  612. EXPORT void
  613. init_fifo(fs)
  614. long fs;
  615. {
  616. errmsgno(EX_BAD, "Fifo not supported.n");
  617. }
  618. EXPORT BOOL
  619. init_faio(tracks, track, bufsize)
  620. int tracks;
  621. track_t *track;
  622. int bufsize;
  623. {
  624. return (FALSE);
  625. }
  626. EXPORT BOOL
  627. await_faio()
  628. {
  629. return (TRUE);
  630. }
  631. EXPORT void
  632. kill_faio()
  633. {
  634. }
  635. EXPORT int
  636. wait_faio()
  637. {
  638. return (0);
  639. }
  640. EXPORT int
  641. faio_read_buf(fd, bp, size)
  642. int fd;
  643. char *bp;
  644. int size;
  645. {
  646. return (0);
  647. }
  648. EXPORT int
  649. faio_get_buf(fd, bpp, size)
  650. int fd;
  651. char **bpp;
  652. int size;
  653. {
  654. return (0);
  655. }
  656. EXPORT void
  657. fifo_stats()
  658. {
  659. }
  660. EXPORT int
  661. fifo_percent(addone)
  662. BOOL addone;
  663. {
  664. return (-1);
  665. }
  666. #endif /* FIFO */