PageRenderTime 50ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/ATF2/control-software/PS_Firmware/EPSC_080115/Modified_Netburner/buffers.cpp

http://atf2flightsim.googlecode.com/
C++ | 806 lines | 629 code | 90 blank | 87 comment | 103 complexity | 437ff1a81f018f1061d1d13ec1e7ba1d MD5 | raw file
Possible License(s): BSD-2-Clause, LGPL-2.0, IPL-1.0, BSD-3-Clause
  1. /* Rev:$Revision: 1.1.1.1 $ */
  2. #include "predef.h"
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include "basictypes.h"
  6. #include "ucosmcfc.h"
  7. #include "constants.h"
  8. #include "utils.h"
  9. #include "ucos.h"
  10. #include "buffers.h"
  11. extern "C"
  12. {
  13. DWORD memcpysum( void *to, const void *frm, int len );
  14. void fmemcpy( void *out, const void *in, size_t n );
  15. }
  16. class BufferCriticalLock
  17. {
  18. OS_CRIT *pcrit;
  19. public:
  20. BufferCriticalLock( OS_CRIT &ocrit )
  21. {
  22. pcrit = &ocrit;
  23. if ( pcrit->OSCritTaskNum == 0xFF )
  24. {
  25. USER_ENTER_CRITICAL();
  26. }
  27. else
  28. {
  29. OSCritEnter( &ocrit, 0 );
  30. }
  31. };
  32. ~BufferCriticalLock()
  33. {
  34. if ( pcrit->OSCritTaskNum == 0xFF )
  35. {
  36. USER_EXIT_CRITICAL();
  37. }
  38. else
  39. {
  40. OSCritLeave( pcrit );
  41. }
  42. }
  43. };
  44. /*-------------------------------------------------------**
  45. ** Allocate the global buffer pool as a static variable. **
  46. **-------------------------------------------------------*/
  47. // ***** added alignment on 4096 byte boundary 06/02/06 DJM *****
  48. pool_buffer static_pool_buffers[BUFFER_POOL_SIZE] __attribute__((aligned(0x2000))); //06/02/06
  49. // ***** static declaration removed to convert to global 10/30/05 DJM *****
  50. //pool_buffer static_pool_buffers[BUFFER_POOL_SIZE] __attribute__((aligned(16)));
  51. //static pool_buffer static_pool_buffers[BUFFER_POOL_SIZE] __attribute__( ( aligned( 16 ) ) ); ;
  52. /*--------------------**
  53. ** Create a free list **
  54. **--------------------*/
  55. buffer_list free_list;
  56. unsigned char free_list_is_initialized;
  57. void ShowBuffers()
  58. {
  59. #ifdef BUFFER_DIAG
  60. BOOL bOneHit = FALSE;
  61. for ( int i = 0; i < BUFFER_POOL_SIZE; i++ )
  62. {
  63. if ( static_pool_buffers[i].bBuffer_state != BO_UNUSED )
  64. {
  65. iprintf( "Buf[%d]=", i );
  66. switch ( static_pool_buffers[i].bBuffer_state )
  67. {
  68. case BO_UNUSED :
  69. /*iprintf("BO_UNUSED ");*/ break;
  70. case BO_SOFTWARE:
  71. iprintf( "BO_SOFTWARE" ); break;
  72. case BO_PRX :
  73. iprintf( "BO_PRX " ); break;
  74. case BO_PTXF :
  75. iprintf( "BO_PTXF " ); break;
  76. case BO_PTXS :
  77. iprintf( "BO_PTXS " ); break;
  78. default:
  79. iprintf( "Unknown State" );
  80. }
  81. if ( static_pool_buffers[i].bBuffer_state != BO_UNUSED )
  82. {
  83. bOneHit = TRUE;
  84. iprintf( " File = %s Line = %d\n",
  85. static_pool_buffers[i].m_fAlloc,
  86. static_pool_buffers[i].m_fline );
  87. }
  88. else
  89. {
  90. iprintf( "\n" );
  91. }
  92. }
  93. }
  94. if ( !bOneHit )
  95. {
  96. iprintf( "All are BO_UNUSED\n" );
  97. }
  98. #endif
  99. }
  100. void ShowIPBuffer( PoolPtr p );
  101. void DumpBuffers()
  102. {
  103. #ifdef BUFFER_DIAG
  104. char c = ' ';
  105. for ( int i = 0; i < BUFFER_POOL_SIZE; i++ )
  106. {
  107. iprintf( "Buf[%d]=", i );
  108. switch ( static_pool_buffers[i].bBuffer_state )
  109. {
  110. case BO_UNUSED :
  111. iprintf( "BO_UNUSED " ); break;
  112. case BO_SOFTWARE:
  113. iprintf( "BO_SOFTWARE" ); break;
  114. case BO_PRX :
  115. iprintf( "BO_PRX " ); break;
  116. case BO_PTXF :
  117. iprintf( "BO_PTXF " ); break;
  118. case BO_PTXS :
  119. iprintf( "BO_PTXS " ); break;
  120. default:
  121. iprintf( "Unknown State" );
  122. }
  123. if ( static_pool_buffers[i].bBuffer_state != BO_UNUSED )
  124. {
  125. iprintf( " File = %s Line = %d\n",
  126. static_pool_buffers[i].m_fAlloc,
  127. static_pool_buffers[i].m_fline );
  128. ShowIPBuffer( static_pool_buffers + i );
  129. iprintf( "Hit n to continue..." );
  130. iprintf( "Hit 'c' to loop ...." );
  131. do
  132. {
  133. if ( c != 'c' )
  134. {
  135. c = getchar();
  136. }
  137. }
  138. while ( ( c != 'n' ) && ( c != 'c' ) );
  139. }
  140. else
  141. {
  142. iprintf( "\n" );
  143. }
  144. }
  145. #endif
  146. }
  147. /*----------------------------------**
  148. ** The Initialize buffers function. **
  149. **This sets up the system buffers **
  150. **----------------------------------*/
  151. void InitBuffers()
  152. {
  153. if ( free_list_is_initialized )
  154. {
  155. return;
  156. }
  157. //Initialize the static free list as it may not get constructed in a embedded environment
  158. free_list.m_Head = free_list.m_Tail = NULL;
  159. free_list.m_wElements = 0;
  160. for ( int i = 0; i < BUFFER_POOL_SIZE; i++ )
  161. {
  162. PoolPtr pp;
  163. pp = static_pool_buffers + i;
  164. pp->bUsageCount = 1;
  165. FreeBuffer( pp );
  166. }
  167. free_list_is_initialized = 1;
  168. }
  169. void IncUsageCount( PoolPtr pp )
  170. {
  171. if ( pp != NULL )
  172. {
  173. pp->bUsageCount++;
  174. }
  175. }
  176. /*---------------------------------------------------**
  177. ** **
  178. ** Frees a buffer and places it in the unused state. **
  179. ** **
  180. **---------------------------------------------------*/
  181. #ifdef BUFFER_DIAG
  182. void FreeBufferX( PoolPtr pp, PCSTR f, int l )
  183. #else
  184. void FreeBuffer( PoolPtr pp )
  185. #endif
  186. {
  187. if ( pp->bUsageCount )
  188. {
  189. pp->bUsageCount--;
  190. }
  191. if ( pp->bUsageCount )
  192. {
  193. return;
  194. }
  195. pp->bBuffer_state = BO_UNUSED;
  196. #ifdef BUFFER_DIAG
  197. pp->m_fAlloc = "FREE";
  198. pp->m_fline = 0;
  199. #endif
  200. free_list.InsertHead( pp );
  201. }
  202. /*-----------------------------------------------------------**
  203. ** **
  204. ** Alocates a Software buffer and returns the buffer number. **
  205. ** **
  206. **-----------------------------------------------------------*/
  207. #ifdef BUFFER_DIAG
  208. PoolPtr GetBufferX( PCSTR f, int l )
  209. #else
  210. PoolPtr GetBuffer()
  211. #endif
  212. {
  213. PoolPtr pp = free_list.RemoveHead();
  214. if ( pp != NULL )
  215. {
  216. pp->bBuffer_state = BO_SOFTWARE;
  217. pp->bUsageCount = 1;
  218. }
  219. #ifdef BUFFER_DIAG
  220. if ( pp == NULL )
  221. {
  222. DBPRINT( DB_BUFFER, "NULL BUFFER" );
  223. }
  224. else
  225. {
  226. pp->m_fAlloc = f;
  227. pp->m_fline = l;
  228. }
  229. #else
  230. if ( pp == NULL )
  231. {
  232. DBPRINT( DB_BUFFER, "NULL BUFFER" );
  233. }
  234. #endif
  235. return pp;
  236. }
  237. #ifdef BUFFER_DIAG
  238. void ChangeOwnerX( PoolPtr pp, PCSTR f, int l )
  239. {
  240. if ( pp != NULL )
  241. {
  242. pp->m_fAlloc = f;
  243. pp->m_fline = l;
  244. }
  245. }
  246. #endif
  247. WORD GetFreeCount()
  248. {
  249. return free_list.GetCount();
  250. };
  251. /*---------------------------------------------------------------------**
  252. ** The folowing functions implment the buffer_list class **
  253. ** This class is used to manage lists of buffers. **
  254. ** All the buffers it manages are from the main buffer pool. **
  255. ** This is setup to be fast, very little error checking is done. **
  256. ** If perform an insert before, remove or insert after with buffer **
  257. ** values that are not part of the buffer list BAD things will happen. **
  258. ** **
  259. ** **
  260. ** All of the internal functions are wrapped in the DISABLE_INTS **
  261. ** ENABLE_INTS Macros. This ensures List Coherency **
  262. ** **
  263. ** **
  264. ** **
  265. **---------------------------------------------------------------------*/
  266. /*-------------------------------------------**
  267. ** Insert a buffer at the head of this list. **
  268. **-------------------------------------------*/
  269. void buffer_list::InsertHead( PoolPtr pp )
  270. {
  271. USER_ENTER_CRITICAL();
  272. pp->pPoolNext = m_Head;
  273. pp->pPoolPrev = NULL;
  274. if ( m_Head != NULL )
  275. {
  276. m_Head->pPoolPrev = pp;
  277. }
  278. else
  279. {
  280. m_Tail = pp;
  281. }
  282. m_Head = pp;
  283. m_wElements++;
  284. USER_EXIT_CRITICAL();
  285. }
  286. /*-------------------------------------------**
  287. ** Insert a buffer at the Tail of this list. **
  288. **-------------------------------------------*/
  289. void buffer_list::InsertTail( PoolPtr pp )
  290. {
  291. USER_ENTER_CRITICAL();
  292. pp->pPoolPrev = m_Tail;
  293. pp->pPoolNext = NULL;
  294. if ( m_Tail != NULL )
  295. {
  296. m_Tail->pPoolNext = pp;
  297. }
  298. else
  299. {
  300. m_Head = pp;
  301. }
  302. m_Tail = pp;
  303. m_wElements++;
  304. USER_EXIT_CRITICAL();
  305. }
  306. /*---------------------------------------------**
  307. ** Insert a buffer before an entry on the list.**
  308. ** NO checking is performed. IF the list does **
  309. ** not have the passed in buffer as a member **
  310. ** BAD THINGS WILL HAPPEN!! **
  311. ** **
  312. **---------------------------------------------*/
  313. void buffer_list::InsertBefore( PoolPtr pp, PoolPtr b4buffer )
  314. {
  315. USER_ENTER_CRITICAL();
  316. m_wElements++;
  317. if ( b4buffer->pPoolPrev == NULL )
  318. {
  319. InsertHead( pp );
  320. }
  321. else
  322. {
  323. pp->pPoolNext = b4buffer;
  324. pp->pPoolPrev = b4buffer->pPoolPrev;
  325. b4buffer->pPoolPrev = pp;
  326. pp->pPoolPrev->pPoolNext = pp;
  327. }
  328. USER_EXIT_CRITICAL();
  329. }
  330. /*---------------------------------------------**
  331. ** Insert a buffer after an entry on the list. **
  332. ** NO checking is performed. IF the list does **
  333. ** not have the passed in buffer as a member **
  334. ** BAD THINGS WILL HAPPEN!! **
  335. ** **
  336. **---------------------------------------------*/
  337. void buffer_list::InsertAfter( PoolPtr pp, PoolPtr after_buffer )
  338. {
  339. USER_ENTER_CRITICAL();
  340. m_wElements++;
  341. if ( after_buffer->pPoolNext == NULL )
  342. {
  343. InsertTail( pp );
  344. }
  345. else
  346. {
  347. pp->pPoolPrev = after_buffer;
  348. pp->pPoolNext = after_buffer->pPoolNext;
  349. after_buffer->pPoolNext = pp;
  350. pp->pPoolNext->pPoolPrev = pp;
  351. }
  352. USER_EXIT_CRITICAL();
  353. }
  354. /*--------------------------------------------**
  355. ** **
  356. ** Remove a buffer from the list. **
  357. ** NO checking is performed. IF the list does **
  358. ** not have the passed in buffer as a member **
  359. ** BAD THINGS WILL HAPPEN!! **
  360. ** **
  361. **--------------------------------------------*/
  362. void buffer_list::Remove( PoolPtr pp )
  363. {
  364. USER_ENTER_CRITICAL();
  365. if ( pp->pPoolNext == NULL )
  366. {
  367. m_Tail = pp->pPoolPrev = NULL;
  368. }
  369. else
  370. {
  371. pp->pPoolNext->pPoolPrev = pp->pPoolPrev;
  372. }
  373. if ( pp->pPoolPrev == NULL )
  374. {
  375. m_Head = pp->pPoolNext;
  376. }
  377. else
  378. {
  379. pp->pPoolPrev->pPoolNext = pp->pPoolNext;
  380. }
  381. m_wElements--;
  382. USER_EXIT_CRITICAL();
  383. pp->pPoolNext = NULL;
  384. pp->pPoolPrev = NULL;
  385. }
  386. PoolPtr LastHead;
  387. /*-----------------------------------------**
  388. ** Get the head of the list. **
  389. ** It return 0 if there are none availible **
  390. **-----------------------------------------*/
  391. PoolPtr buffer_list::RemoveHead()
  392. {
  393. USER_ENTER_CRITICAL();
  394. PoolPtr rv = m_Head;
  395. if ( m_Head != NULL )
  396. {
  397. LastHead=m_Head;
  398. m_wElements--;
  399. if ( m_Head == m_Tail )
  400. {
  401. m_Head = m_Tail = NULL;
  402. }
  403. else
  404. {
  405. m_Head = rv->pPoolNext;
  406. m_Head->pPoolPrev = NULL;
  407. }
  408. }
  409. USER_EXIT_CRITICAL();
  410. return rv;
  411. }
  412. /*-----------------------------------------**
  413. ** Get the end of the list. **
  414. ** It return 0 if there are none availible **
  415. **-----------------------------------------*/
  416. PoolPtr buffer_list::RemoveTail()
  417. {
  418. USER_ENTER_CRITICAL();
  419. m_wElements--;
  420. PoolPtr rv = m_Tail;
  421. if ( rv != NULL )
  422. {
  423. if ( m_Head == m_Tail )
  424. {
  425. m_Head = m_Tail = NULL;
  426. }
  427. else
  428. {
  429. m_Tail = rv->pPoolPrev;
  430. m_Tail->pPoolNext = NULL;
  431. }
  432. }
  433. USER_EXIT_CRITICAL();
  434. return rv;
  435. }
  436. void ShowBuffer( PoolPtr pb )
  437. {
  438. iprintf( "Buffer[%p] State =", pb );
  439. switch ( pb->bBuffer_state )
  440. {
  441. case BO_UNUSED :
  442. iprintf( " BO_UNUSED " ); break;
  443. case BO_SOFTWARE:
  444. iprintf( " BO_SOFTWARE" ); break;
  445. case BO_PRX :
  446. iprintf( " BO_PRX " ); break;
  447. case BO_PTXF :
  448. iprintf( " BO_PTXF " ); break;
  449. case BO_PTXS :
  450. iprintf( " BO_PTXS " ); break;
  451. default :
  452. iprintf( "Unknown %d", pb->bBuffer_state );
  453. }
  454. iprintf( " Size = %d\n", pb->usedsize );
  455. for ( WORD i = 0; i < pb->usedsize; i++ )
  456. {
  457. iprintf( "%02x ", ( int ) pb->pData[i] );
  458. if ( ( i % 16 ) == 15 )
  459. {
  460. iprintf( "\n" );
  461. }
  462. }
  463. iprintf( "\n" );
  464. }
  465. //Data is read in the tail
  466. //and read out the head.
  467. WORD fifo_buffer_storage::SpaceAvail()
  468. {
  469. BufferCriticalLock oscs( m_critical_section ); /*Locks the OS the destructor will unlock*/
  470. WORD storage = ( m_MaxSegments - m_Segments_Stored ) * ETHER_BUFFER_SIZE;
  471. if ( m_Tail != NULL )
  472. {
  473. storage += ( ETHER_BUFFER_SIZE - m_Tail->usedsize );
  474. }
  475. return storage;
  476. }
  477. WORD fifo_buffer_storage::SpaceUsed()
  478. {
  479. return m_BytesStored;
  480. }
  481. int fifo_buffer_storage::ReadData( PBYTE pCopyTo, int max_bytes )
  482. {
  483. int bytes_copied = 0;
  484. BufferCriticalLock oscs( m_critical_section ); /*Locks the OS the destructor will unlock*/
  485. if ( m_Head != NULL )
  486. {
  487. while ( ( m_Head ) && ( bytes_copied < max_bytes ) )
  488. {
  489. int bytes_avail;
  490. //How much is avail in the head segment?
  491. bytes_avail = m_Head->usedsize - ( m_Head->pBufQueuePointer - m_Head->pData );
  492. //Limit it to the amount we can copy
  493. if ( ( bytes_avail + bytes_copied ) > max_bytes )
  494. {
  495. memcpy( pCopyTo + bytes_copied,
  496. m_Head->pBufQueuePointer,
  497. max_bytes - bytes_copied );
  498. m_Head->pBufQueuePointer += ( max_bytes - bytes_copied );
  499. bytes_copied = max_bytes;
  500. }
  501. else
  502. {
  503. //Copy the whole buffer
  504. memcpy( pCopyTo + bytes_copied, m_Head->pBufQueuePointer, bytes_avail );
  505. bytes_copied += bytes_avail;
  506. PoolPtr pp = m_Head;
  507. m_Head = m_Head->pPoolNext;
  508. FreeBuffer( pp );
  509. if ( m_Head == NULL )
  510. {
  511. m_Tail = NULL;
  512. }
  513. m_Segments_Stored--;
  514. }
  515. }
  516. m_BytesStored -= bytes_copied;
  517. }
  518. return bytes_copied;
  519. }
  520. int fifo_buffer_storage::ReadDatawSum( PBYTE pCopyTo, int max_bytes, DWORD &csum )
  521. {
  522. int bytes_copied = 0;
  523. BufferCriticalLock oscs( m_critical_section ); /*Locks the OS the destructor will unlock*/
  524. csum = 0;
  525. if ( m_Head != NULL )
  526. {
  527. while ( ( m_Head ) && ( bytes_copied < max_bytes ) )
  528. {
  529. int bytes_avail;
  530. //How much is avail in the head segment?
  531. bytes_avail = m_Head->usedsize - ( m_Head->pBufQueuePointer - m_Head->pData );
  532. if ( bytes_copied & 1 )
  533. {
  534. /* Odd checksum correction */
  535. *( pCopyTo + bytes_copied ) = *( m_Head->pBufQueuePointer );
  536. csum += *( m_Head->pBufQueuePointer );
  537. m_Head->pBufQueuePointer++;
  538. bytes_avail--;
  539. bytes_copied++;
  540. if ( bytes_avail == 0 )
  541. {
  542. PoolPtr pp = m_Head;
  543. m_Head = m_Head->pPoolNext;
  544. FreeBuffer( pp );
  545. if ( m_Head == NULL )
  546. {
  547. m_Tail = NULL;
  548. }
  549. m_Segments_Stored--;
  550. break;
  551. }
  552. if ( bytes_copied == max_bytes )
  553. {
  554. break;
  555. }
  556. }
  557. //Limit it to the amount we can copy
  558. if ( ( bytes_avail + bytes_copied ) > max_bytes )
  559. {
  560. csum += memcpysum( pCopyTo + bytes_copied,
  561. m_Head->pBufQueuePointer,
  562. max_bytes - bytes_copied );
  563. m_Head->pBufQueuePointer += ( max_bytes - bytes_copied );
  564. bytes_copied = max_bytes;
  565. }
  566. else
  567. {
  568. //Copy the whole buffer
  569. csum += memcpysum( pCopyTo + bytes_copied,
  570. m_Head->pBufQueuePointer,
  571. bytes_avail );
  572. bytes_copied += bytes_avail;
  573. PoolPtr pp = m_Head;
  574. m_Head = m_Head->pPoolNext;
  575. FreeBuffer( pp );
  576. if ( m_Head == NULL )
  577. {
  578. m_Tail = NULL;
  579. }
  580. m_Segments_Stored--;
  581. }
  582. }
  583. m_BytesStored -= bytes_copied;
  584. }
  585. return bytes_copied;
  586. }
  587. int fifo_buffer_storage::WriteData( PBYTE pCopyFrom, int num_bytes )
  588. {
  589. int bytes_copied = 0;
  590. BufferCriticalLock oscs( m_critical_section ); /*Locks the OS the destructor will unlock*/
  591. if ( m_Tail == NULL )
  592. {
  593. m_Head = m_Tail = GetBuffer();
  594. if ( m_Head == NULL )
  595. {
  596. DBPRINT( DB_BUFFER, "Write Buffer Data Failed To alloc" );
  597. return 0;
  598. }
  599. m_Tail->pBufQueuePointer = m_Tail->pData;
  600. m_Tail->usedsize = 0;
  601. m_Segments_Stored++;
  602. m_Tail->pPoolNext = NULL;
  603. }
  604. else if ( ( m_Tail->usedsize == ETHER_BUFFER_SIZE ) &&
  605. ( m_Segments_Stored < m_MaxSegments ) )
  606. {
  607. m_Tail->pPoolNext = GetBuffer();
  608. if ( m_Tail->pPoolNext == NULL )
  609. {
  610. DBPRINT( DB_BUFFER, "Write Buffer Data Failed" );
  611. return 0;
  612. }
  613. m_Tail = m_Tail->pPoolNext;
  614. m_Tail->pBufQueuePointer = m_Tail->pData;
  615. m_Tail->usedsize = 0;
  616. m_Tail->pPoolNext = NULL;
  617. m_Segments_Stored++;
  618. }
  619. while ( ( bytes_copied < num_bytes ) )
  620. {
  621. int Can_Copy = ( ETHER_BUFFER_SIZE - m_Tail->usedsize );
  622. if ( ( Can_Copy + bytes_copied ) > num_bytes )
  623. {
  624. Can_Copy = num_bytes - bytes_copied;
  625. fmemcpy( m_Tail->pData + m_Tail->usedsize, pCopyFrom + bytes_copied, Can_Copy );
  626. m_Tail->usedsize += Can_Copy;
  627. bytes_copied += Can_Copy;
  628. }
  629. else
  630. {
  631. fmemcpy( m_Tail->pData + m_Tail->usedsize, pCopyFrom + bytes_copied, Can_Copy );
  632. m_Tail->usedsize += Can_Copy;
  633. bytes_copied += Can_Copy;
  634. if ( m_Segments_Stored < m_MaxSegments )
  635. {
  636. m_Tail->pPoolNext = GetBuffer();
  637. if ( m_Tail->pPoolNext == NULL )
  638. {
  639. DBPRINT( DB_BUFFER, "Wriite Buffer Faile " );
  640. return 0;
  641. }
  642. m_Tail = m_Tail->pPoolNext;
  643. m_Tail->pBufQueuePointer = m_Tail->pData;
  644. m_Tail->usedsize = 0;
  645. m_Tail->pPoolNext = NULL;
  646. m_Segments_Stored++;
  647. }
  648. else
  649. {
  650. break;
  651. } //Break out of while
  652. }//else a full buffer copy
  653. }//while
  654. m_BytesStored += bytes_copied;
  655. return bytes_copied;
  656. }
  657. fifo_buffer_storage::fifo_buffer_storage( BYTE max_buffers, BYTE use_fromisr )
  658. {
  659. Init( max_buffers, use_fromisr );
  660. }
  661. fifo_buffer_storage::~fifo_buffer_storage()
  662. {
  663. Reset( 0 );
  664. }
  665. void fifo_buffer_storage::Init( BYTE max_buffers, BYTE use_fromisr )
  666. {
  667. if ( use_fromisr )
  668. {
  669. /* We cheat and store a flag in the critical section */
  670. m_critical_section.OSCritTaskNum = 0xFF;
  671. }
  672. else
  673. {
  674. OSCritInit( &m_critical_section );
  675. }
  676. m_Head = m_Tail = NULL;
  677. m_Segments_Stored = 0;
  678. m_BytesStored = 0;
  679. m_MaxSegments = max_buffers;
  680. };
  681. void fifo_buffer_storage::SetMaxBuffers( BYTE max_buffers )
  682. {
  683. BufferCriticalLock oscs( m_critical_section ); /*Locks the OS the destructor will unlock*/
  684. m_MaxSegments = max_buffers;
  685. }
  686. void fifo_buffer_storage::Reset( BYTE max_buffers )
  687. {
  688. BufferCriticalLock oscs( m_critical_section ); /*Locks the OS the destructor will unlock*/
  689. PoolPtr pp = m_Head;
  690. while ( pp )
  691. {
  692. m_Head = pp->pPoolNext;
  693. FreeBuffer( pp );
  694. pp = m_Head;
  695. }
  696. m_Head = m_Tail = NULL;
  697. m_Segments_Stored = 0;
  698. m_BytesStored = 0;
  699. m_MaxSegments = max_buffers;
  700. }
  701. BOOL fifo_buffer_storage::Empty()
  702. {
  703. return ( m_BytesStored == 0 );
  704. }
  705. BOOL fifo_buffer_storage::Full()
  706. {
  707. if ( m_MaxSegments - m_Segments_Stored )
  708. {
  709. return 0;
  710. }
  711. if ( ( m_Tail != NULL ) && ( ETHER_BUFFER_SIZE - m_Tail->usedsize ) )
  712. {
  713. return 0;
  714. }
  715. return 1;
  716. }