Commit bff5f99c authored by Andrey Filippov's avatar Andrey Filippov
Browse files

minor cleanup before increasing threads

parent 1070f517
Loading
Loading
Loading
Loading
+6 −36
Original line number Original line Diff line number Diff line
@@ -281,12 +281,10 @@ void camogm_init(camogm_state *state, char *pipe_name, uint16_t port_num)
	state->rawdev.mmap_default_size = MMAP_CHUNK_SIZE;  // only used for camogm_read
	state->rawdev.mmap_default_size = MMAP_CHUNK_SIZE;  // only used for camogm_read
	state->sock_port = port_num;
	state->sock_port = port_num;


//	state->writer_params.data_ready = false;
	state->writer_params.chunk_page_prep =  0; // will prepare page 0
	state->writer_params.chunk_page_prep =  0; // will prepare page 0
	state->writer_params.chunk_page_write = 0; // will write page 0
	state->writer_params.chunk_page_write = 0; // will write page 0
	state->writer_params.writev_run =       false;
	state->writer_params.writev_run =       false;



	state->writer_params.exit_thread = false;
	state->writer_params.exit_thread = false;
	state->writer_params.state = STATE_STOPPED;
	state->writer_params.state = STATE_STOPPED;


@@ -559,7 +557,7 @@ int sendImageFrame(camogm_state *state)
// This is probably needed only for Quicktime (not to exceed already allocated frame index)
// This is probably needed only for Quicktime (not to exceed already allocated frame index)
	if (!state->rawdev_op && (state->frameno >= (state->max_frames))) {
	if (!state->rawdev_op && (state->frameno >= (state->max_frames))) {
		D3(fprintf(debug_file, "sendImageFrame:1: state->frameno(0x%x) >= state->max_frames(0x%x)\n", state->frameno, state->max_frames));
		D3(fprintf(debug_file, "sendImageFrame:1: state->frameno(0x%x) >= state->max_frames(0x%x)\n", state->frameno, state->max_frames));
		return -CAMOGM_FRAME_CHANGED;
		return -CAMOGM_FRAME_NEXTFILE;
	}
	}
// Format changed?
// Format changed?
//   D3(fprintf (debug_file,"sendImageFrame: format=%d, set_format=%d\n", state->format, state->set_format));
//   D3(fprintf (debug_file,"sendImageFrame: format=%d, set_format=%d\n", state->format, state->set_format));
@@ -569,14 +567,14 @@ int sendImageFrame(camogm_state *state)
		return -CAMOGM_FRAME_CHANGED;
		return -CAMOGM_FRAME_CHANGED;
	}
	}
//   check if file size is exceeded (assuming fopen),-CAMOGM_FRAME_CHANGED will trigger a new segment
//   check if file size is exceeded (assuming fopen),-CAMOGM_FRAME_CHANGED will trigger a new segment
	if ((state->vf) && (state->segment_length >= 0) && (ftell(state->vf) > state->segment_length)) {
	if (!state->rawdev_op && (state->vf) && (state->segment_length >= 0) && (ftell(state->vf) > state->segment_length)) {
		D3(fprintf(debug_file, "sendImageFrame:3: segment length exceeded\n"));
		D3(fprintf(debug_file, "sendImageFrame:3: segment length exceeded\n"));
		return -CAMOGM_FRAME_CHANGED;
		return -CAMOGM_FRAME_NEXTFILE;
	}
	}
//same for open
//same for open
	if (!state->rawdev_op && ((state->ivf) >= 0) && (state->segment_length >= 0) && (lseek(state->ivf, 0, SEEK_CUR) > state->segment_length)) {
	if (!state->rawdev_op && ((state->ivf) >= 0) && (state->segment_length >= 0) && (lseek(state->ivf, 0, SEEK_CUR) > state->segment_length)) {
		D3(fprintf(debug_file, "sendImageFrame:4: segment length exceeded\n"));
		D3(fprintf(debug_file, "sendImageFrame:4: segment length exceeded\n"));
		return -CAMOGM_FRAME_CHANGED;
		return -CAMOGM_FRAME_NEXTFILE;
	}
	}
// check the frame pointer is valid
// check the frame pointer is valid
	if ((fp = lseek(state->fd_circ[port], state->cirbuf_rp[port], SEEK_SET)) < 0) {
	if ((fp = lseek(state->fd_circ[port], state->cirbuf_rp[port], SEEK_SET)) < 0) {
@@ -733,7 +731,7 @@ int sendImageFrame(camogm_state *state)
	state->frameno++;
	state->frameno++;
	state->cirbuf_rp[port] = lseek(state->fd_circ[port], LSEEK_CIRC_NEXT, SEEK_END);
	state->cirbuf_rp[port] = lseek(state->fd_circ[port], LSEEK_CIRC_NEXT, SEEK_END);
	if (state->cirbuf_rp[port] < 0) {
	if (state->cirbuf_rp[port] < 0) {
		D2(fprintf(debug_file, "_14a_: sendImageFrame(): frame broken - buffer overrun\n"));
		D0(fprintf(debug_file, "_14a_: sendImageFrame(): frame broken - buffer overrun\n"));
		return -CAMOGM_FRAME_BROKEN;
		return -CAMOGM_FRAME_BROKEN;
	}
	}


@@ -748,16 +746,6 @@ int sendImageFrame(camogm_state *state)
	}
	}
	D3(fprintf(debug_file,"cirbuf_rp to next frame = 0x%x\n", state->cirbuf_rp[port]));
	D3(fprintf(debug_file,"cirbuf_rp to next frame = 0x%x\n", state->cirbuf_rp[port]));


//	end_time = get_fpga_time(state->fd_fparmsall[port], port);
//	unsigned int mbps; // write speed, MB/s
//	unsigned long long time_diff; // time elapsed, in microseconds
//	time_diff = ((end_time.tv_sec * 1000000 + end_time.tv_usec) - (start_time.tv_sec * 1000000 + start_time.tv_usec));
//	mbps = ((double)state->rawdev.last_jpeg_size / (double)1048576) / ((double)time_diff / (double)1000000);
//	D6(fprintf(debug_file, "Frame start time: %ld:%ld; frame end time: %ld:%ld; last frame size: %lu\n",
//			start_time.tv_sec, start_time.tv_usec,
//			end_time.tv_sec, end_time.tv_usec,
//			state->rawdev.last_jpeg_size));
//	D6(fprintf(debug_file, "Write speed: %d MB/s\n", mbps));
	D6(fprintf(debug_file, "Exit sendImageFrame() OK @ %07d\n",get_fpga_usec(state->fd_fparmsall[0], 0)));
	D6(fprintf(debug_file, "Exit sendImageFrame() OK @ %07d\n",get_fpga_usec(state->fd_fparmsall[0], 0)));


	return 0;
	return 0;
@@ -1718,29 +1706,13 @@ int listener_loop(camogm_state *state)
				D6(fprintf(debug_file, "No compressed frame ready, waited for the next frame sync for port %d @ %07d\n",curr_port,get_fpga_usec(state->fd_fparmsall[0], 0)));
				D6(fprintf(debug_file, "No compressed frame ready, waited for the next frame sync for port %d @ %07d\n",curr_port,get_fpga_usec(state->fd_fparmsall[0], 0)));
				break;
				break;
				// do not analyze next frame (may be non-existing), will do that next time
				// do not analyze next frame (may be non-existing), will do that next time
				/*
				fp0 = lseek(state->fd_circ[curr_port], 0, SEEK_CUR); // need to skip uncompressed frame, LWIR16 turns compressor off
				if (fp0 < 0) {
					D0(fprintf(debug_file, "%s:line %d got broken frame (%d) before waiting for ready\n", __FILE__, __LINE__, fp0));
					rslt = CAMOGM_FRAME_BROKEN;
				} else {
					fp1 = lseek(state->fd_circ[curr_port], LSEEK_CIRC_WAIT, SEEK_END);
					if (fp1 < 0) {
						D0(fprintf(debug_file, "%s:line %d got broken frame (%d) while waiting for ready. Before that fp0=0x%x\n", __FILE__, __LINE__, fp1, fp0));
						rslt = CAMOGM_FRAME_BROKEN;
					} else {
						D6(fprintf(debug_file, "No compressed frame ready, skipped 1 frame sync for port %d @ %07d\n",curr_port,get_fpga_usec(state->fd_fparmsall[0], 0)));
						break;
					}
				}
				*/
				// no break
				// no break
			case  CAMOGM_FRAME_CHANGED:     // frame parameters have changed
			case  CAMOGM_FRAME_CHANGED:     // frame parameters have changed
			case  CAMOGM_FRAME_NEXTFILE:    // next file needed (need to switch to a new file (time/size exceeded limit)
			case  CAMOGM_FRAME_NEXTFILE:    // next file needed (need to switch to a new file (time/size exceeded limit)
			case  CAMOGM_FRAME_INVALID:     // invalid frame pointer
			case  CAMOGM_FRAME_INVALID:     // invalid frame pointer
			case  CAMOGM_FRAME_BROKEN:      // frame broken (buffer overrun)
			case  CAMOGM_FRAME_BROKEN:      // frame broken (buffer overrun)
				// restart the file
				// restart the file
				D3(fprintf(debug_file,"%s:line %d - sendImageFrame() returned -%d\n", __FILE__, __LINE__, rslt));
				D0(fprintf(debug_file,"%s:line %d - sendImageFrame() returned -%d\n", __FILE__, __LINE__, rslt));
				camogm_stop(state);
				camogm_stop(state);
				state->prog_state = STATE_RESTARTING;
				state->prog_state = STATE_RESTARTING;
				camogm_start(state);
				camogm_start(state);
@@ -2048,8 +2020,6 @@ unsigned int select_port(camogm_state *state)
		}
		}
	}
	}
	if ((state->prog_state == STATE_STARTING) || (state->prog_state == STATE_RUNNING)) {
	if ((state->prog_state == STATE_STARTING) || (state->prog_state == STATE_RUNNING)) {
//		if (lseek(state->fd_circ[port], LSEEK_CIRC_READY, SEEK_END) < 0) {
//	fprintf(debug_file, "selected port: %i, min free size = %08ld @ %07d\n", chn, min_sz, get_fpga_usec(state->fd_fparmsall[0], 0));
		D1(if ((chn >=0) && (lseek(state->fd_circ[chn], LSEEK_CIRC_READY, SEEK_END) >= 0)) \
		D1(if ((chn >=0) && (lseek(state->fd_circ[chn], LSEEK_CIRC_READY, SEEK_END) >= 0)) \
				fprintf(debug_file, "selected port: %i, min free size = %08ld ", chn, min_sz); \
				fprintf(debug_file, "selected port: %i, min free size = %08ld ", chn, min_sz); \
				else if (debug_level >= 6) fprintf(debug_file,"no port is ready @ %07d\n", get_fpga_usec(state->fd_fparmsall[0], 0)));
				else if (debug_level >= 6) fprintf(debug_file,"no port is ready @ %07d\n", get_fpga_usec(state->fd_fparmsall[0], 0)));
+0 −1
Original line number Original line Diff line number Diff line
@@ -92,7 +92,6 @@
#define JPEG_TRAILER_LEN          2  ///< The size in bytes of JPEG trailer
#define JPEG_TRAILER_LEN          2  ///< The size in bytes of JPEG trailer
#define CIRCBUF_ALIGNMENT_SIZE   32  ///< Align of CIRCBUF entries
#define CIRCBUF_ALIGNMENT_SIZE   32  ///< Align of CIRCBUF entries



// Switching CHUNK -> SEGMENT
// Switching CHUNK -> SEGMENT
#define PAGE_PHYS              4096 //  512 // alignment size for O_DIRECT, may be different from LBA block size that is 512
#define PAGE_PHYS              4096 //  512 // alignment size for O_DIRECT, may be different from LBA block size that is 512
enum segments  {
enum segments  {
+1 −1
Original line number Original line Diff line number Diff line
@@ -323,7 +323,7 @@ void reset_segments(camogm_state *state, int all, int page)
}
}


/** Convert LBA to byte offset used for lseek */
/** Convert LBA to byte offset used for lseek */
off64_t lba_to_offset(uint64_t lba)
uint64_t lba_to_offset(uint64_t lba)
//uint64_t lba_to_offset(uint64_t lba)
//uint64_t lba_to_offset(uint64_t lba)
{
{
	return lba * PHY_BLOCK_SIZE;
	return lba * PHY_BLOCK_SIZE;
+1 −15
Original line number Original line Diff line number Diff line
@@ -24,24 +24,10 @@
#include "camogm.h"
#include "camogm.h"
// TODO: Change PHY_BLOCK_SIZE to 4096 as it is 4096 - no, most SSDs are still 512
// TODO: Change PHY_BLOCK_SIZE to 4096 as it is 4096 - no, most SSDs are still 512
#define PHY_BLOCK_SIZE            512            ///< Physical disk block size - still 512 even for the OS with 4096
#define PHY_BLOCK_SIZE            512            ///< Physical disk block size - still 512 even for the OS with 4096
//#define PHY_BLOCK_SIZE            4096           ///< Physical disk block size
//#define JPEG_MARKER_LEN           2              ///< The size in bytes of JPEG marker
//#define JPEG_MARKER_LEN           2              ///< The size in bytes of JPEG marker
#define JPEG_SIZE_LEN             2              ///< The size in bytes of JPEG marker length field
#define JPEG_SIZE_LEN             2              ///< The size in bytes of JPEG marker length field
#define INCLUDE_REM               1              ///< Include REM buffer to total size calculation
#define INCLUDE_REM               1              ///< Include REM buffer to total size calculation
#define EXCLUDE_REM               0              ///< Exclude REM buffer from total size calculation
#define EXCLUDE_REM               0              ///< Exclude REM buffer from total size calculation
#if 0
#define MAX_DATA_CHUNKS           9              ///< An array or JPEG frame chunks contains pointers to JPEG leading marker,
                                                 ///< JPEG header, Exif data if present, stuffing bytes chunk which aligns
                                                 ///< the frame size to disk sector boundary, JPEG data which
                                                 ///< can be split into two chunks, align buffers, JPEG
                                                 ///< trailing marker, and pointer to a buffer containing the remainder of a
                                                 ///< frame. Nine chunks of data in total.
                                                 ///
#define ALIGNMENT_SIZE            32             ///< Align buffers length to this amount of bytes
/** Common buffer should be large enough to contain JPEG header, Exif, some alignment bytes and remainder from previous frame */
#define COMMON_BUFF_SZ            MAX_EXIF_SIZE + JPEG_HEADER_MAXSIZE + ALIGNMENT_SIZE + 2 * PHY_BLOCK_SIZE
#define REM_BUFF_SZ               2 * PHY_BLOCK_SIZE
#endif


/** Symbolic names for slots in buffer pointers. Buffer alignment function relies on the order of these names, so
/** Symbolic names for slots in buffer pointers. Buffer alignment function relies on the order of these names, so
 * new names can be added but the overall order should not be changed */
 * new names can be added but the overall order should not be changed */
@@ -62,7 +48,7 @@ int init_align_buffers(camogm_state *state);
void deinit_align_buffers(camogm_state *state);
void deinit_align_buffers(camogm_state *state);
void reset_segments(camogm_state *state, int all, int page);
void reset_segments(camogm_state *state, int all, int page);
size_t remap_vectors(camogm_state *state); //, struct iovec *chunks);
size_t remap_vectors(camogm_state *state); //, struct iovec *chunks);
off64_t lba_to_offset(uint64_t lba);
uint64_t lba_to_offset(uint64_t lba);
int vectaligntail(struct iovec *dest);
int vectaligntail(struct iovec *dest);




+9 −120
Original line number Original line Diff line number Diff line
@@ -17,12 +17,14 @@


/** @brief This define is needed to use lseek64 and should be set before includes */
/** @brief This define is needed to use lseek64 and should be set before includes */
#define _LARGEFILE64_SOURCE
#define _LARGEFILE64_SOURCE
#define __USE_GNU // for O_DIRECT
//#define __USE_GNU // for O_DIRECT
#define _GNU_SOURCE // for O_DIRECT
#include <linux/raw.h> // for O_DIRECT
#include <linux/raw.h> // for O_DIRECT
#include <unistd.h>
#include <unistd.h>
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <fcntl.h>
#include <fcntl.h>
//#include <bits/fcntl.h> // 'O_DIRECT'
#include <sys/uio.h>
#include <sys/uio.h>
#include <errno.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/stat.h>
@@ -46,10 +48,6 @@
static void *jpeg_writer(void *thread_args);
static void *jpeg_writer(void *thread_args);
static int save_state_file(const camogm_state *state);
static int save_state_file(const camogm_state *state);


#ifdef BUFFER_KVEC
static unsigned char * image_ubuffer = NULL;
#endif

/**
/**
 * Emulate writev() by consecutive write()
 * Emulate writev() by consecutive write()
 * @param __fd
 * @param __fd
@@ -70,29 +68,7 @@ ssize_t emul_writev (int fd, const struct iovec *iovec, int count) {
				debug_level = 6;
				debug_level = 6;
				return -1;
				return -1;
			}
			}

#ifdef BUFFER_KVEC
			D6(fprintf(debug_file, "Trying direct writing of %d bytes from %p, data = 0x%llx\n",\
					iovec[i].iov_len, iovec[i].iov_base, ((uint64_t*) iovec[i].iov_base)[0]));
			D6(syslog (LOG_INFO, "Trying direct writing of %d bytes from %p, data = 0x%llx\n",\
					iovec[i].iov_len, iovec[i].iov_base, ((uint64_t*) iovec[i].iov_base)[0]));
			wlen = write (fd, iovec[i].iov_base, iovec[i].iov_len);
			wlen = write (fd, iovec[i].iov_base, iovec[i].iov_len);
			if (wlen < 0) {
				D6(fprintf(debug_file, "Got write error = %d, copying %d bytes from %p to %p\n",\
						-wlen, iovec[i].iov_len, iovec[i].iov_base, image_ubuffer));

				if (iovec[i].iov_len > MAX_IMAGE_ALIGNED){
					D0(fprintf(debug_file, "image too big: %d > %d\n", iovec[i].iov_len, MAX_IMAGE_ALIGNED));
					return -1;
				}
				memcpy(image_ubuffer, iovec[i].iov_base, iovec[i].iov_len);
				D6(fprintf(debug_file, "data=0x%llx\n", ((uint64_t*) image_ubuffer)[0]));
				D6(syslog (LOG_INFO, "data = 0x%llx\n",((uint64_t*) image_ubuffer)[0]));
				wlen = write (fd,image_ubuffer, iovec[i].iov_len);
			}
#else
			wlen = write (fd, iovec[i].iov_base, iovec[i].iov_len);
#endif
			if (wlen < 0) {
			if (wlen < 0) {
				D0(fprintf(debug_file, "Error %d while trying direct writing of %d bytes from %p, data = 0x%llx, segment=%d\n",\
				D0(fprintf(debug_file, "Error %d while trying direct writing of %d bytes from %p, data = 0x%llx, segment=%d\n",\
						wlen, iovec[i].iov_len, iovec[i].iov_base, ((uint64_t*) iovec[i].iov_base)[0],i ));
						wlen, iovec[i].iov_len, iovec[i].iov_base, ((uint64_t*) iovec[i].iov_base)[0],i ));
@@ -254,16 +230,6 @@ int camogm_init_jpeg(camogm_state *state)
			ret = -1;
			ret = -1;
			return ret;
			return ret;
		}
		}

#ifdef BUFFER_KVEC
		image_ubuffer = (unsigned char *) aligned_alloc (PAGE_PHYS, MAX_IMAGE_ALIGNED);
		if (image_ubuffer == NULL){
			D0(fprintf(debug_file, "Can not initialize image_ubuffer\n"));
			ret =  -1;
		} else {
			D3(fprintf(debug_file, "Allocated image buffer for copying kernel data @ %p size= %d bytes\n", image_ubuffer, MAX_IMAGE_ALIGNED));
		}
#endif
	}
	}


	return ret;
	return ret;
@@ -289,13 +255,6 @@ void camogm_free_jpeg(camogm_state *state)
	state->writer_params.exit_thread = false;
	state->writer_params.exit_thread = false;


	deinit_align_buffers(state);
	deinit_align_buffers(state);
#ifdef BUFFER_KVEC
	if (image_ubuffer != NULL){
		D3(fprintf(debug_file, "Deallcating image buffer for copying kernel data @ %p size= %d bytes\n", image_ubuffer, MAX_IMAGE_ALIGNED));
		free (image_ubuffer);
		image_ubuffer = NULL;
	}
#endif
}
}


/** Calculate the total length of current frame */
/** Calculate the total length of current frame */
@@ -322,7 +281,7 @@ int camogm_start_jpeg(camogm_state *state)
{
{
	char * slash;
	char * slash;
	int rslt;
	int rslt;
	off64_t offset;
	uint64_t offset;


	if (!state->rawdev_op) {
	if (!state->rawdev_op) {
		strcpy(state->path, state->path_prefix);   // make state->path a directory name (will be replaced when the frames will be written)
		strcpy(state->path, state->path_prefix);   // make state->path a directory name (will be replaced when the frames will be written)
@@ -344,7 +303,10 @@ int camogm_start_jpeg(camogm_state *state)
			D0(fprintf(debug_file, "Could not get write pointer from state file, recording will start from the beginning of partition: "
			D0(fprintf(debug_file, "Could not get write pointer from state file, recording will start from the beginning of partition: "
					"%s\n", state->rawdev.rawdev_path));
					"%s\n", state->rawdev.rawdev_path));
		}
		}
		state->writer_params.blockdev_fd = open(state->rawdev.rawdev_path, O_RDWR | __O_DIRECT);  // __O_DIRECT);
//		state->writer_params.blockdev_fd = open(state->rawdev.rawdev_path, O_RDWR | 0x40000); // __O_DIRECT);  // __O_DIRECT);
		state->writer_params.blockdev_fd = open(state->rawdev.rawdev_path, O_RDWR | O_DIRECT); // __O_DIRECT);  // __O_DIRECT);
		// int mode = fcntl(fd, F_GETFL);
		D0(syslog (LOG_INFO, "Raw %s is opened in 0x%08x mode, __O_DIRECT=0x%08x, O_DIRECT=0x%08x", state->rawdev.rawdev_path, fcntl(state->writer_params.blockdev_fd, F_GETFL), __O_DIRECT, O_DIRECT));
		if (state->writer_params.blockdev_fd < 0) {
		if (state->writer_params.blockdev_fd < 0) {
			D0(fprintf(debug_file, "Error opening block device: %s\n", state->rawdev.rawdev_path));
			D0(fprintf(debug_file, "Error opening block device: %s\n", state->rawdev.rawdev_path));
			return -CAMOGM_FRAME_FILE_ERR;
			return -CAMOGM_FRAME_FILE_ERR;
@@ -487,26 +449,6 @@ int camogm_end_jpeg(camogm_state *state) // TODO: Resolve multippage !
			//*************** See if another buffer(s) must be cleared too? or even use chunk_page_write
			//*************** See if another buffer(s) must be cleared too? or even use chunk_page_write
			reset_segments(state, 1, state->writer_params.chunk_page_prep % SEGMENTS_PAGES);
			reset_segments(state, 1, state->writer_params.chunk_page_prep % SEGMENTS_PAGES);
		}
		}
#if 0
		bytes = prep_last_block(state, state->writer_params.chunk_page_prep  % SEGMENTS_PAGES);
		if (bytes > 0) {
			D6(fprintf(debug_file, "Write last block of data, size = %d\n", bytes));
			// the remaining data block is placed in CHUNK_COMMON buffer, write just this buffer
			iovlen = emul_writev(state->writer_params.blockdev_fd,
					&state->writer_params.data_chunks[CHUNK_COMMON + (state->writer_params.chunk_page_prep % SEGMENTS_PAGES) * FILE_CHUNKS_NUM], 1);
			if (iovlen < bytes) {
				D0(fprintf(debug_file, "emul_writev error: %s (returned %i, expected %i)\n", strerror(errno), iovlen, bytes));
				state->writer_params.last_ret_val = -CAMOGM_FRAME_FILE_ERR;
			} else {
				// update statistic, just one block written
				state->writer_params.lba_current += 1;
				state->rawdev.total_rec_len += bytes;
			}
			//			reset_chunks(state->writer_params.data_chunks, 1);
			//*************** See if another buffer(s) must be cleared too? or even use chunk_page_write
			reset_segments(state, 1, state->writer_params.chunk_page_prep % SEGMENTS_PAGES);
		}
#endif
		pthread_mutex_unlock(&state->writer_params.writer_mutex);
		pthread_mutex_unlock(&state->writer_params.writer_mutex);


		D6(fprintf(debug_file, "Closing block device %s\n", state->rawdev.rawdev_path));
		D6(fprintf(debug_file, "Closing block device %s\n", state->rawdev.rawdev_path));
@@ -531,20 +473,13 @@ void *jpeg_writer(void *thread_args)
	int dbg_us1=0, dbg_us2=0, dbg_us; // save usec for difference
	int dbg_us1=0, dbg_us2=0, dbg_us; // save usec for difference
	long dbg_pos;
	long dbg_pos;
	int reset_rem;
	int reset_rem;
//	int chunk_index, i, i0, i1;
	int i, i0, i1;
	int i, i0, i1;
	ssize_t iovlen, l, ll, l0, l1, blocks_write, wpage;
	ssize_t iovlen, l, ll, l0, l1, blocks_write, wpage;
	bool process = true, has_data_to_write = false;
	bool process = true, has_data_to_write = false;
//	struct iovec chunks_iovec[SEGMENTS_PAGES][FILE_CHUNKS_NUM];
	struct iovec split_chunk;
	struct iovec split_chunk;


	camogm_state *state = (camogm_state *)thread_args;
	camogm_state *state = (camogm_state *)thread_args;
	struct writer_params *params = &state->writer_params;
	struct writer_params *params = &state->writer_params;
///	unsigned char dummy_buff[PHY_BLOCK_SIZE];

//	memset((void *)chunks_iovec, 0, sizeof(struct iovec) * SEGMENTS_PAGES * FILE_CHUNKS_NUM);
	// lock, will only allow main thread while a) waiting for write buffer, and b) waiting for emul_writev
////	pthread_mutex_lock(&params->writer_mutex);
	params->state = STATE_RUNNING;
	params->state = STATE_RUNNING;
	D6(fprintf(debug_file, "_w000_:  Before jpeg_writer loop @ %07d\n", get_fpga_usec(state->fd_fparmsall[0], 0))); // before the debug file is set !
	D6(fprintf(debug_file, "_w000_:  Before jpeg_writer loop @ %07d\n", get_fpga_usec(state->fd_fparmsall[0], 0))); // before the debug file is set !
	while (process) {
	while (process) {
@@ -560,27 +495,8 @@ void *jpeg_writer(void *thread_args)
		has_data_to_write = params->chunk_page_prep != params->chunk_page_write;
		has_data_to_write = params->chunk_page_prep != params->chunk_page_write;
		pthread_mutex_unlock(&params->writer_mutex);
		pthread_mutex_unlock(&params->writer_mutex);
		D6(fprintf(debug_file, "_w00.5_: (%d, %d) @ %07d\n", params->chunk_page_prep, params->chunk_page_write,get_fpga_usec(state->fd_fparmsall[0], 0)));
		D6(fprintf(debug_file, "_w00.5_: (%d, %d) @ %07d\n", params->chunk_page_prep, params->chunk_page_write,get_fpga_usec(state->fd_fparmsall[0], 0)));
//		if (params->data_ready) {
		if (has_data_to_write) {
		if (has_data_to_write) {
			D6(fprintf(debug_file, "_w01_: got write data (%d > %d) @ %07d\n", params->chunk_page_prep, params->chunk_page_write,get_fpga_usec(state->fd_fparmsall[0], 0)));
			D6(fprintf(debug_file, "_w01_: got write data (%d > %d) @ %07d\n", params->chunk_page_prep, params->chunk_page_write,get_fpga_usec(state->fd_fparmsall[0], 0)));
			/* dummy read cycle from (approximately) the beginning of previous frame;
			 * this is a debug feature used to find disk errors */
			/*//temporary disable for simplicity 05/21/2023
			if (state->writer_params.dummy_read) {
				ssize_t data_len;
				off64_t curr_offset = lseek64(state->writer_params.blockdev_fd, 0, SEEK_CUR);
				off64_t offset = lba_to_offset(state->writer_params.lba_current - state->writer_params.lba_start) - state->rawdev.last_jpeg_size;
				offset = offset / PHY_BLOCK_SIZE;
				lseek64(state->writer_params.blockdev_fd, offset, SEEK_SET);
				data_len = read(state->writer_params.blockdev_fd, dummy_buff, PHY_BLOCK_SIZE);
				if (data_len < PHY_BLOCK_SIZE) {
					D6(fprintf(debug_file, "Dummy read error: requested %d, read %d, %s\n", PHY_BLOCK_SIZE, data_len, strerror(errno)));
				}
				lseek64(state->writer_params.blockdev_fd, curr_offset, SEEK_SET);
			}
			*/
			/* end of dummy read cycle */

			l = 0;
			l = 0;
			reset_rem = 0;
			reset_rem = 0;
			state->writer_params.last_ret_val = 0;
			state->writer_params.last_ret_val = 0;
@@ -597,10 +513,6 @@ void *jpeg_writer(void *thread_args)
			// chunk_index = get_data_buffers(state, chunks_iovec[wpage], FILE_CHUNKS_NUM, wpage);
			// chunk_index = get_data_buffers(state, chunks_iovec[wpage], FILE_CHUNKS_NUM, wpage);
			// assuming write is block-aligned
			// assuming write is block-aligned
			if (num_write_segments > 0) {
			if (num_write_segments > 0) {
#if 0
				for (i = 0; i < chunk_index; i++)
					l += chunks_iovec[wpage][i].iov_len;
#endif
				// Moved rollover here
				// Moved rollover here
				blocks_write = l / PHY_BLOCK_SIZE; // here LBA, 512
				blocks_write = l / PHY_BLOCK_SIZE; // here LBA, 512
				if (state->writer_params.lba_current + blocks_write <= state->writer_params.lba_end) { // almost always - single write
				if (state->writer_params.lba_current + blocks_write <= state->writer_params.lba_end) { // almost always - single write
@@ -610,12 +522,11 @@ void *jpeg_writer(void *thread_args)
					D6(fprintf(debug_file, "_w02_: starting emul_writev@ %07d\n", dbg_us1));
					D6(fprintf(debug_file, "_w02_: starting emul_writev@ %07d\n", dbg_us1));
					state->writer_params.writev_run = true;
					state->writer_params.writev_run = true;
					pthread_cond_signal(&params->main_cond);
					pthread_cond_signal(&params->main_cond);
//					iovlen = emul_writev(state->writer_params.blockdev_fd, chunks_iovec[wpage], chunk_index);
					iovlen = emul_writev(state->writer_params.blockdev_fd, write_segments, num_write_segments);
					iovlen = emul_writev(state->writer_params.blockdev_fd, write_segments, num_write_segments);
					state->writer_params.writev_run = false;
					state->writer_params.writev_run = false;
					D2(dbg_us=get_fpga_usec(state->fd_fparmsall[0], 0); fprintf(debug_file, "_w03_: finished emul_writev, pos%%block = %ld, pos= %ld  @ %07d (+ %07d, +%07d)\n",dbg_pos % PHY_BLOCK_SIZE, dbg_pos,dbg_us, (dbg_us-dbg_us1), (dbg_us-dbg_us2)));
					D2(dbg_us=get_fpga_usec(state->fd_fparmsall[0], 0); fprintf(debug_file, "_w03_: finished emul_writev, pos%%block = %ld, pos= %ld  @ %07d (+ %07d, +%07d)\n",dbg_pos % PHY_BLOCK_SIZE, dbg_pos,dbg_us, (dbg_us-dbg_us1), (dbg_us-dbg_us2)));
					D3(syslog (LOG_INFO, "_w03_: finished emul_writev, pos= %ld, len = %d(0x%x) @ %07d (+ %07d, +%07d)", dbg_pos, iovlen, iovlen, dbg_us, (dbg_us-dbg_us1), (dbg_us-dbg_us2)));
					D3(syslog (LOG_INFO, "_w03_: finished emul_writev, pos= %ld, len = %d(0x%x) @ %07d (+ %07d, +%07d)", dbg_pos, iovlen, iovlen, dbg_us, (dbg_us-dbg_us1), (dbg_us-dbg_us2)));
					D3(dbg_us2=dbg_us);
					D2(dbg_us2=dbg_us);
					if (iovlen < l) {
					if (iovlen < l) {
						D0(fprintf(debug_file, "emul_writev error: %s (returned %i, expected %i)\n", strerror(errno), iovlen, l));
						D0(fprintf(debug_file, "emul_writev error: %s (returned %i, expected %i)\n", strerror(errno), iovlen, l));
						state->writer_params.last_ret_val = -CAMOGM_FRAME_FILE_ERR;
						state->writer_params.last_ret_val = -CAMOGM_FRAME_FILE_ERR;
@@ -642,8 +553,6 @@ void *jpeg_writer(void *thread_args)
							ll += write_segments[i0].iov_len;
							ll += write_segments[i0].iov_len;
						}
						}
						// save split chunk
						// save split chunk
///						split_chunk.iov_base = chunks_iovec[wpage][i0].iov_base;
///						split_chunk.iov_len =  chunks_iovec[wpage][i0].iov_len;
						split_chunk.iov_base = write_segments[i0].iov_base;
						split_chunk.iov_base = write_segments[i0].iov_base;
						split_chunk.iov_len =  write_segments[i0].iov_len;
						split_chunk.iov_len =  write_segments[i0].iov_len;
						i1 = i0; // index of the first chunk in a second write
						i1 = i0; // index of the first chunk in a second write
@@ -655,7 +564,6 @@ void *jpeg_writer(void *thread_args)
						state->writer_params.lba_current = state->writer_params.lba_start;
						state->writer_params.lba_current = state->writer_params.lba_start;
						state->writer_params.writev_run = true;
						state->writer_params.writev_run = true;
						pthread_cond_signal(&params->main_cond);
						pthread_cond_signal(&params->main_cond);
///						iovlen = emul_writev(state->writer_params.blockdev_fd, chunks_iovec[wpage], i0);
						iovlen = emul_writev(state->writer_params.blockdev_fd, write_segments, i0);
						iovlen = emul_writev(state->writer_params.blockdev_fd, write_segments, i0);
						state->writer_params.writev_run = false;
						state->writer_params.writev_run = false;
						lseek(state->writer_params.blockdev_fd, 0, SEEK_SET); // regardless of error - rewind
						lseek(state->writer_params.blockdev_fd, 0, SEEK_SET); // regardless of error - rewind
@@ -668,21 +576,6 @@ void *jpeg_writer(void *thread_args)
							D6(fprintf(debug_file, "(1 of 2) Current position in block device: %lld\n", lseek64(state->writer_params.blockdev_fd, 0, SEEK_CUR)));
							D6(fprintf(debug_file, "(1 of 2) Current position in block device: %lld\n", lseek64(state->writer_params.blockdev_fd, 0, SEEK_CUR)));
							// update split chunk to use its second part, shift chunks
							// update split chunk to use its second part, shift chunks
							if (l1 > 0) { // length to be written after rollover
							if (l1 > 0) { // length to be written after rollover
#if 0
								if (chunks_iovec[wpage][i1].iov_len != split_chunk.iov_len) { // it was split
									D0(fprintf(debug_file, "chunk %d was split, full length = %d, writtren = %d\n", i1, split_chunk.iov_len, chunks_iovec[wpage][i1].iov_len));
									chunks_iovec[wpage][i1].iov_base += chunks_iovec[wpage][i1].iov_len;
									chunks_iovec[wpage][i1].iov_len = split_chunk.iov_len - chunks_iovec[wpage][i1].iov_len;
								}
								// shift chunks
								for (i0 = i1; i0 < chunk_index; i0++){
									chunks_iovec[wpage][i0 - i1] = chunks_iovec[wpage][i0];
								}
								state->writer_params.writev_run = true;
								pthread_cond_signal(&params->main_cond);
								iovlen = emul_writev(state->writer_params.blockdev_fd, chunks_iovec[wpage], chunk_index - i1);
								state->writer_params.writev_run = false;
#endif
								if (write_segments[i1].iov_len != split_chunk.iov_len) { // it was split
								if (write_segments[i1].iov_len != split_chunk.iov_len) { // it was split
									D0(fprintf(debug_file, "chunk %d was split, full length = %d, writtren = %d\n", i1, split_chunk.iov_len, write_segments[i1].iov_len));
									D0(fprintf(debug_file, "chunk %d was split, full length = %d, writtren = %d\n", i1, split_chunk.iov_len, write_segments[i1].iov_len));
									write_segments[i1].iov_base += write_segments[i1].iov_len;
									write_segments[i1].iov_base += write_segments[i1].iov_len;
@@ -690,7 +583,6 @@ void *jpeg_writer(void *thread_args)
								}
								}
								// shift chunks
								// shift chunks
								for (i0 = i1; i0 < num_write_segments; i0++){
								for (i0 = i1; i0 < num_write_segments; i0++){
///									write_segments[i0 - i1] = write_segments[i0];
									write_segments[i0 - i1].iov_base = write_segments[i0].iov_base;
									write_segments[i0 - i1].iov_base = write_segments[i0].iov_base;
									write_segments[i0 - i1].iov_len =  write_segments[i0].iov_len;
									write_segments[i0 - i1].iov_len =  write_segments[i0].iov_len;
								}
								}
@@ -723,7 +615,6 @@ void *jpeg_writer(void *thread_args)
				reset_rem = 1;
				reset_rem = 1;
			}
			}
			// release main thread
			// release main thread
///			reset_chunks(state, reset_rem, state->writer_params.chunk_page_write % SEGMENTS_PAGES);
			reset_segments(state, reset_rem, state->writer_params.chunk_page_write % SEGMENTS_PAGES);
			reset_segments(state, reset_rem, state->writer_params.chunk_page_write % SEGMENTS_PAGES);
			pthread_mutex_lock(&params->writer_mutex);
			pthread_mutex_lock(&params->writer_mutex);
			params->chunk_page_write = (params->chunk_page_write + 1) % (2 * SEGMENTS_PAGES);
			params->chunk_page_write = (params->chunk_page_write + 1) % (2 * SEGMENTS_PAGES);
@@ -738,8 +629,6 @@ void *jpeg_writer(void *thread_args)
		}
		}
	}
	}
	params->state = STATE_STOPPED;
	params->state = STATE_STOPPED;
//	pthread_mutex_unlock(&state->writer_params.writer_mutex);
	D5(fprintf(debug_file, "_w07_: Exit from recording thread\n")); // never?
	D5(fprintf(debug_file, "_w07_: Exit from recording thread\n")); // never?

	return NULL;
	return NULL;
}
}
Loading