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

SCSI/ASPI

开发平台:

MultiPlatform

  1. /* @(#)ringbuff.c 1.2 99/12/19 Copyright 1998,1999 Heiko Eissfeldt */
  2. #ifndef lint
  3. static char     sccsid[] =
  4. "@(#)ringbuff.c 1.2 99/12/19 Copyright 1998,1999 Heiko Eissfeldt";
  5. #endif
  6. #include "config.h"
  7. #include <stdlib.h>
  8. #include <stdio.h>
  9. #include <standard.h>
  10. #if defined (HAVE_UNISTD_H) && (HAVE_UNISTD_H == 1)
  11. #include <sys/types.h>
  12. #include <unistd.h>
  13. #endif
  14. #if defined(HAVE_SEMGET) && defined(USE_SEMAPHORES)
  15. #include <sys/ipc.h>
  16. #include <sys/sem.h>
  17. #endif
  18. #include <scg/scsitransp.h>
  19. #include "mytype.h"
  20. #include "global.h"
  21. #include "interface.h"
  22. #include "ringbuff.h"
  23. #include "semshm.h"
  24. #undef WARN_INTERRUPT
  25. #undef _DEBUG
  26. #include <assert.h>
  27. static void occupy_buffer __PR((void));
  28. myringbuff **fill_buffer;
  29. myringbuff **last_buffer;
  30. volatile unsigned long *total_segments_read;
  31. volatile unsigned long *total_segments_written;
  32. volatile int *child_waits;
  33. volatile int *parent_waits;
  34. volatile int *in_lendian;
  35. static myringbuff *previous_read_buffer;
  36. static unsigned int total_buffers;
  37. #define SEMS 2
  38. #define defined_buffers() ((*total_segments_read) - (*total_segments_written))
  39. #define free_buffers() (total_buffers - defined_buffers())
  40. #define occupied_buffers() (defined_buffers())
  41. void set_total_buffers(num_buffers, mysem_id)
  42. unsigned int num_buffers;
  43. int mysem_id;
  44. {
  45. #if defined(HAVE_SEMGET) && defined(USE_SEMAPHORES)
  46.   union my_semun mysemun;
  47.   mysemun.val   = 0;
  48.   if (semctl(mysem_id,(int) DEF_SEM,SETVAL,mysemun) < 0) {
  49.     perror("semctl DEF_SEM");
  50.   }
  51.   mysemun.val   = num_buffers;
  52.   if (semctl(mysem_id,(int) FREE_SEM,SETVAL,mysemun) < 0) {
  53.     perror("semctl FREE_SEM");
  54.   }
  55. #else
  56.   PRETEND_TO_USE(mysem_id);
  57. #endif
  58.   total_buffers = num_buffers;
  59.   /* initialize pointers */
  60.   *fill_buffer = *last_buffer = previous_read_buffer = NULL;
  61. #ifdef DEBUG_SHM
  62. fprintf(stderr, "init: fill_b = %p,  last_b = %pn", *fill_buffer, *last_buffer);
  63. #endif
  64. }
  65. const myringbuff *get_previous_read_buffer()
  66. {
  67.   assert(previous_read_buffer != NULL);
  68.   assert(previous_read_buffer != *fill_buffer);
  69.   return previous_read_buffer;
  70. }
  71. const myringbuff *get_fill_buffer()
  72. {
  73.   assert(*fill_buffer != NULL);
  74.   assert(previous_read_buffer != *fill_buffer);
  75.   return *fill_buffer;
  76. }
  77. void define_buffer()
  78. {
  79.   assert(defined_buffers() < total_buffers);
  80. #ifdef _DEBUG
  81. #if 0
  82.   fprintf(stderr,"stop  reading  %p - %pn",
  83.                  *fill_buffer, (char *)(*fill_buffer) + ENTRY_SIZE -1);
  84. #endif
  85. #endif
  86.   if (*last_buffer == NULL)
  87.     *last_buffer = *fill_buffer;
  88. #ifdef DEBUG_SHM
  89. fprintf(stderr, "define: fill_b = %p,  last_b = %pn", *fill_buffer, *last_buffer);
  90. #endif
  91.   (*total_segments_read)++;
  92.   semrelease(sem_id,DEF_SEM,1);
  93. }
  94. void drop_buffer()
  95. {
  96.   assert(free_buffers() < total_buffers);
  97.   assert(occupied_buffers() > 0);
  98. #ifdef _DEBUG
  99. #if 0
  100.   fprintf(stderr," stop  writing %p - %p ",
  101.                  *last_buffer, (char *)(*last_buffer) + ENTRY_SIZE -1);
  102. #endif
  103. #endif
  104.   if (*last_buffer == NULL)
  105.     *last_buffer = *fill_buffer;
  106.   else
  107.     *last_buffer = INC(*last_buffer);
  108. #ifdef DEBUG_SHM
  109. fprintf(stderr, "drop: fill_b = %p,  last_b = %pn", *fill_buffer, *last_buffer);
  110. #endif
  111.   (*total_segments_written)++;
  112.   semrelease(sem_id,FREE_SEM, 1);
  113. }
  114. void drop_all_buffers()
  115. {
  116.   (*total_segments_written) = (*total_segments_read);
  117.   semrelease(sem_id,FREE_SEM, total_buffers);
  118. }
  119. static void occupy_buffer()
  120. {
  121.   assert(occupied_buffers() <= total_buffers);
  122.   previous_read_buffer = *fill_buffer;
  123.   if (*fill_buffer == NULL) {
  124.     *fill_buffer = RB_BASE;
  125.   } else {
  126.     *fill_buffer = INC(*fill_buffer);
  127.   }
  128. }
  129. #if defined HAVE_FORK_AND_SHAREDMEM
  130. myringbuff * get_next_buffer()
  131. {
  132. #ifdef WARN_INTERRUPT
  133.   if (free_buffers() <= 0) {
  134.     fprintf(stderr, "READER waits!! r=%lu, w=%lun", *total_segments_read,
  135. *total_segments_written);
  136.   }
  137. #endif
  138.   /* wait for a new buffer to become available */
  139.   if (semrequest(sem_id,FREE_SEM) != 0) {
  140.     /* semaphore operation failed.
  141.        try again...
  142.        */
  143.     fprintf(stderr, "child reader sem request failedn");
  144.     exit(3);
  145.   }
  146. #if 0
  147.   fprintf(stderr,"start reading  %p - %pn",
  148.                  *fill_buffer, (char *)(*fill_buffer) + ENTRY_SIZE -1);
  149. #endif
  150.   occupy_buffer();
  151. #ifdef DEBUG_SHM
  152. fprintf(stderr, "next: fill_b = %p,  last_b = %p, @last = %pn", *fill_buffer, *last_buffer, last_buffer);
  153. #endif
  154.   return *fill_buffer;
  155. }
  156. myringbuff *get_oldest_buffer()
  157. {
  158.   myringbuff *retval;
  159. #ifdef WARN_INTERRUPT
  160.   if (free_buffers() == total_buffers) {
  161.     fprintf(stderr, "WRITER waits!! r=%lu, w=%lun", *total_segments_read,
  162. *total_segments_written);
  163.   }
  164. #endif
  165.   /* wait for buffer to be defined */
  166.   if (semrequest(sem_id,DEF_SEM) != 0) {
  167.     /* semaphore operation failed. */
  168.     perror("request defined buff:");
  169.     fprintf(stderr, "parent writer sem request failedn");
  170.   }
  171.   retval = *last_buffer;
  172. #if 0
  173.   fprintf(stderr," begin writing %p - %pn",
  174.                   retval, (char *)retval + ENTRY_SIZE -1);
  175. #endif
  176.   return retval;
  177. }
  178. #else /* HAVE_FORK_AND_SHAREDMEM */
  179. myringbuff * get_next_buffer()
  180. {
  181.   occupy_buffer();
  182.   return *fill_buffer;
  183. }
  184. myringbuff * get_oldest_buffer()
  185. {
  186.   return *fill_buffer;
  187. }
  188. #endif /* HAVE_FORK_AND_SHAREDMEM */