You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					124 lines
				
				2.5 KiB
			
		
		
			
		
	
	
					124 lines
				
				2.5 KiB
			| 
											6 years ago
										 | #ifndef BUFFERING_H
 | ||
|  | #define BUFFERING_H
 | ||
|  | 
 | ||
|  | #include <stdbool.h>
 | ||
|  | #include <pthread.h>
 | ||
|  | 
 | ||
|  | #ifdef __cplusplus
 | ||
|  | extern "C" {
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | // Tripple buffering helper
 | ||
|  | 
 | ||
|  | typedef struct TBuffer {
 | ||
|  |     pthread_mutex_t lock;
 | ||
|  |     pthread_cond_t cv;
 | ||
|  |     int efd;
 | ||
|  | 
 | ||
|  |     bool* reading;
 | ||
|  |     int pending_idx;
 | ||
|  | 
 | ||
|  |     int num_bufs;
 | ||
|  |     const char* name;
 | ||
|  | 
 | ||
|  |     void (*release_cb)(void* c, int idx);
 | ||
|  |     void *cb_cookie;
 | ||
|  | 
 | ||
|  |     bool stopped;
 | ||
|  | } TBuffer;
 | ||
|  | 
 | ||
|  | // num_bufs must be at least the number of buffers that can be acquired simultaniously plus two
 | ||
|  | void tbuffer_init(TBuffer *tb, int num_bufs, const char* name);
 | ||
|  | 
 | ||
|  | void tbuffer_init2(TBuffer *tb, int num_bufs, const char* name,
 | ||
|  |   void (*release_cb)(void* c, int idx),
 | ||
|  |   void* cb_cookie);
 | ||
|  | 
 | ||
|  | // returns an eventfd that signals if a buffer is ready and tbuffer_acquire shouldn't to block.
 | ||
|  | // useful to polling on multiple tbuffers.
 | ||
|  | int tbuffer_efd(TBuffer *tb);
 | ||
|  | 
 | ||
|  | // Chooses a buffer that's not reading or pending
 | ||
|  | int tbuffer_select(TBuffer *tb);
 | ||
|  | 
 | ||
|  | // Called when the writer is done with their buffer
 | ||
|  | //  - Wakes up the reader if it's waiting
 | ||
|  | //  - releases the pending buffer if the reader's too slow
 | ||
|  | void tbuffer_dispatch(TBuffer *tb, int idx);
 | ||
|  | 
 | ||
|  | // Called when the reader wants a new buffer, will return -1 when stopped
 | ||
|  | int tbuffer_acquire(TBuffer *tb);
 | ||
|  | 
 | ||
|  | // Called when the reader is done with their buffer
 | ||
|  | void tbuffer_release(TBuffer *tb, int idx);
 | ||
|  | 
 | ||
|  | void tbuffer_release_all(TBuffer *tb);
 | ||
|  | 
 | ||
|  | void tbuffer_stop(TBuffer *tb);
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | // pool: buffer pool + queue thing...
 | ||
|  | 
 | ||
|  | #define POOL_MAX_TBUFS 8
 | ||
|  | #define POOL_MAX_QUEUES 8
 | ||
|  | 
 | ||
|  | typedef struct Pool Pool;
 | ||
|  | 
 | ||
|  | typedef struct PoolQueue {
 | ||
|  |   pthread_mutex_t lock;
 | ||
|  |   pthread_cond_t cv;
 | ||
|  |   Pool* pool;
 | ||
|  |   bool inited;
 | ||
|  |   bool stopped;
 | ||
|  |   int efd;
 | ||
|  |   int num_bufs;
 | ||
|  |   int num;
 | ||
|  |   int head, tail;
 | ||
|  |   int* idx;
 | ||
|  | } PoolQueue;
 | ||
|  | 
 | ||
|  | int poolq_pop(PoolQueue *s);
 | ||
|  | int poolq_efd(PoolQueue *s);
 | ||
|  | void poolq_release(PoolQueue *c, int idx);
 | ||
|  | 
 | ||
|  | typedef struct Pool {
 | ||
|  |   pthread_mutex_t lock;
 | ||
|  |   bool stopped;
 | ||
|  |   int num_bufs;
 | ||
|  |   int counter;
 | ||
|  | 
 | ||
|  |   int* ts;
 | ||
|  |   int* refcnt;
 | ||
|  | 
 | ||
|  |   void (*release_cb)(void* c, int idx);
 | ||
|  |   void *cb_cookie;
 | ||
|  | 
 | ||
|  |   int num_tbufs;
 | ||
|  |   TBuffer tbufs[POOL_MAX_TBUFS];
 | ||
|  |   PoolQueue queues[POOL_MAX_QUEUES];
 | ||
|  | } Pool;
 | ||
|  | 
 | ||
|  | void pool_init(Pool *s, int num_bufs);
 | ||
|  | void pool_init2(Pool *s, int num_bufs,
 | ||
|  |   void (*release_cb)(void* c, int idx), void* cb_cookie);
 | ||
|  | 
 | ||
|  | TBuffer* pool_get_tbuffer(Pool *s);
 | ||
|  | 
 | ||
|  | PoolQueue* pool_get_queue(Pool *s);
 | ||
|  | void pool_release_queue(PoolQueue *q);
 | ||
|  | 
 | ||
|  | int pool_select(Pool *s);
 | ||
|  | void pool_push(Pool *s, int idx);
 | ||
|  | void pool_acquire(Pool *s, int idx);
 | ||
|  | void pool_release(Pool *s, int idx);
 | ||
|  | void pool_stop(Pool *s);
 | ||
|  | 
 | ||
|  | 
 | ||
|  | #ifdef __cplusplus
 | ||
|  | }  // extern "C"
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #endif
 |