nrelease - fix/improve livecd
[dragonfly.git] / contrib / xz / src / liblzma / common / outqueue.h
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 /// \file       outqueue.h
4 /// \brief      Output queue handling in multithreaded coding
5 //
6 //  Author:     Lasse Collin
7 //
8 //  This file has been put into the public domain.
9 //  You can do whatever you want with this file.
10 //
11 ///////////////////////////////////////////////////////////////////////////////
12
13 #include "common.h"
14
15
16 /// Output buffer for a single thread
17 typedef struct {
18         /// Pointer to the output buffer of lzma_outq.buf_size_max bytes
19         uint8_t *buf;
20
21         /// Amount of data written to buf
22         size_t size;
23
24         /// Additional size information
25         lzma_vli unpadded_size;
26         lzma_vli uncompressed_size;
27
28         /// True when no more data will be written into this buffer.
29         ///
30         /// \note       This is read by another thread and thus access
31         ///             to this variable needs a mutex.
32         bool finished;
33
34 } lzma_outbuf;
35
36
37 typedef struct {
38         /// Array of buffers that are used cyclically.
39         lzma_outbuf *bufs;
40
41         /// Memory allocated for all the buffers
42         uint8_t *bufs_mem;
43
44         /// Amount of buffer space available in each buffer
45         size_t buf_size_max;
46
47         /// Number of buffers allocated
48         uint32_t bufs_allocated;
49
50         /// Position in the bufs array. The next buffer to be taken
51         /// into use is bufs[bufs_pos].
52         uint32_t bufs_pos;
53
54         /// Number of buffers in use
55         uint32_t bufs_used;
56
57         /// Position in the buffer in lzma_outq_read()
58         size_t read_pos;
59
60 } lzma_outq;
61
62
63 /**
64  * \brief       Calculate the memory usage of an output queue
65  *
66  * \return      Approximate memory usage in bytes or UINT64_MAX on error.
67  */
68 extern uint64_t lzma_outq_memusage(uint64_t buf_size_max, uint32_t threads);
69
70
71 /// \brief      Initialize an output queue
72 ///
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
85 ///                             out of order.
86 ///
87 /// \return     - LZMA_OK
88 ///             - LZMA_MEM_ERROR
89 ///
90 extern lzma_ret lzma_outq_init(
91                 lzma_outq *outq, const lzma_allocator *allocator,
92                 uint64_t buf_size_max, uint32_t threads);
93
94
95 /// \brief      Free the memory associated with the output queue
96 extern void lzma_outq_end(lzma_outq *outq, const lzma_allocator *allocator);
97
98
99 /// \brief      Get a new buffer
100 ///
101 /// lzma_outq_has_buf() must be used to check that there is a buffer
102 /// available before calling lzma_outq_get_buf().
103 ///
104 extern lzma_outbuf *lzma_outq_get_buf(lzma_outq *outq);
105
106
107 /// \brief      Test if there is data ready to be read
108 ///
109 /// Call to this function must be protected with the same mutex that
110 /// is used to protect lzma_outbuf.finished.
111 ///
112 extern bool lzma_outq_is_readable(const lzma_outq *outq);
113
114
115 /// \brief      Read finished data
116 ///
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
120 ///                             out[*out_pos].
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
125 ///
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.
130 ///
131 /// \note       This reads lzma_outbuf.finished variables and thus call
132 ///             to this function needs to be protected with a mutex.
133 ///
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);
138
139
140 /// \brief      Test if there is at least one buffer free
141 ///
142 /// This must be used before getting a new buffer with lzma_outq_get_buf().
143 ///
144 static inline bool
145 lzma_outq_has_buf(const lzma_outq *outq)
146 {
147         return outq->bufs_used < outq->bufs_allocated;
148 }
149
150
151 /// \brief      Test if the queue is completely empty
152 static inline bool
153 lzma_outq_is_empty(const lzma_outq *outq)
154 {
155         return outq->bufs_used == 0;
156 }