1 ///////////////////////////////////////////////////////////////////////////////
4 /// \brief Output queue handling in multithreaded coding
6 // Author: Lasse Collin
8 // This file has been put into the public domain.
9 // You can do whatever you want with this file.
11 ///////////////////////////////////////////////////////////////////////////////
16 /// Output buffer for a single thread
18 /// Pointer to the output buffer of lzma_outq.buf_size_max bytes
21 /// Amount of data written to buf
24 /// Additional size information
25 lzma_vli unpadded_size;
26 lzma_vli uncompressed_size;
28 /// True when no more data will be written into this buffer.
30 /// \note This is read by another thread and thus access
31 /// to this variable needs a mutex.
38 /// Array of buffers that are used cyclically.
41 /// Memory allocated for all the buffers
44 /// Amount of buffer space available in each buffer
47 /// Number of buffers allocated
48 uint32_t bufs_allocated;
50 /// Position in the bufs array. The next buffer to be taken
51 /// into use is bufs[bufs_pos].
54 /// Number of buffers in use
57 /// Position in the buffer in lzma_outq_read()
64 * \brief Calculate the memory usage of an output queue
66 * \return Approximate memory usage in bytes or UINT64_MAX on error.
68 extern uint64_t lzma_outq_memusage(uint64_t buf_size_max, uint32_t threads);
71 /// \brief Initialize an output queue
73 /// \param outq Pointer to an output queue. Before calling
74 /// this function the first time, *outq should
75 /// have been zeroed with memzero() so that this
76 /// function knows that there are no previous
77 /// allocations to free.
78 /// \param allocator Pointer to allocator or NULL
79 /// \param buf_size_max Maximum amount of data that a single buffer
80 /// in the queue may need to store.
81 /// \param threads Number of buffers that may be in use
82 /// concurrently. Note that more than this number
83 /// of buffers will actually get allocated to
84 /// improve performance when buffers finish
90 extern lzma_ret lzma_outq_init(
91 lzma_outq *outq, const lzma_allocator *allocator,
92 uint64_t buf_size_max, uint32_t threads);
95 /// \brief Free the memory associated with the output queue
96 extern void lzma_outq_end(lzma_outq *outq, const lzma_allocator *allocator);
99 /// \brief Get a new buffer
101 /// lzma_outq_has_buf() must be used to check that there is a buffer
102 /// available before calling lzma_outq_get_buf().
104 extern lzma_outbuf *lzma_outq_get_buf(lzma_outq *outq);
107 /// \brief Test if there is data ready to be read
109 /// Call to this function must be protected with the same mutex that
110 /// is used to protect lzma_outbuf.finished.
112 extern bool lzma_outq_is_readable(const lzma_outq *outq);
115 /// \brief Read finished data
117 /// \param outq Pointer to an output queue
118 /// \param out Beginning of the output buffer
119 /// \param out_pos The next byte will be written to
121 /// \param out_size Size of the out buffer; the first byte into
122 /// which no data is written to is out[out_size].
123 /// \param unpadded_size Unpadded Size from the Block encoder
124 /// \param uncompressed_size Uncompressed Size from the Block encoder
126 /// \return - LZMA: All OK. Either no data was available or the buffer
127 /// being read didn't become empty yet.
128 /// - LZMA_STREAM_END: The buffer being read was finished.
129 /// *unpadded_size and *uncompressed_size were set.
131 /// \note This reads lzma_outbuf.finished variables and thus call
132 /// to this function needs to be protected with a mutex.
134 extern lzma_ret lzma_outq_read(lzma_outq *restrict outq,
135 uint8_t *restrict out, size_t *restrict out_pos,
136 size_t out_size, lzma_vli *restrict unpadded_size,
137 lzma_vli *restrict uncompressed_size);
140 /// \brief Test if there is at least one buffer free
142 /// This must be used before getting a new buffer with lzma_outq_get_buf().
145 lzma_outq_has_buf(const lzma_outq *outq)
147 return outq->bufs_used < outq->bufs_allocated;
151 /// \brief Test if the queue is completely empty
153 lzma_outq_is_empty(const lzma_outq *outq)
155 return outq->bufs_used == 0;