Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
E
elphel-apps-camogm
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Elphel
elphel-apps-camogm
Commits
4e936992
Commit
4e936992
authored
Mar 22, 2017
by
Mikhail Karpenko
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Write from separate thread in test program, test O_DIRECT flag
parent
db8cd54c
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
111 additions
and
5 deletions
+111
-5
camogm.c
src/camogm.c
+4
-0
camogm_test.c
src/camogm_test.c
+107
-5
No files found.
src/camogm.c
View file @
4e936992
...
@@ -365,6 +365,7 @@ int camogm_start(camogm_state *state)
...
@@ -365,6 +365,7 @@ int camogm_start(camogm_state *state)
if
(
is_chn_active
(
state
,
chn
))
{
if
(
is_chn_active
(
state
,
chn
))
{
// Check/set circbuf read pointer
// Check/set circbuf read pointer
D3
(
fprintf
(
debug_file
,
"1: state->cirbuf_rp=0x%x
\n
"
,
state
->
cirbuf_rp
[
chn
]));
D3
(
fprintf
(
debug_file
,
"1: state->cirbuf_rp=0x%x
\n
"
,
state
->
cirbuf_rp
[
chn
]));
D3
(
fprintf
(
debug_file
,
"1a: compressed frame number = %i
\n
"
,
lseek
(
state
->
fd_circ
[
chn
],
LSEEK_CIRC_GETFRAME
,
SEEK_END
)));
if
((
state
->
cirbuf_rp
[
chn
]
<
0
)
||
(
lseek
(
state
->
fd_circ
[
chn
],
state
->
cirbuf_rp
[
chn
],
SEEK_SET
)
<
0
)
||
(
lseek
(
state
->
fd_circ
[
chn
],
LSEEK_CIRC_VALID
,
SEEK_END
)
<
0
))
{
if
((
state
->
cirbuf_rp
[
chn
]
<
0
)
||
(
lseek
(
state
->
fd_circ
[
chn
],
state
->
cirbuf_rp
[
chn
],
SEEK_SET
)
<
0
)
||
(
lseek
(
state
->
fd_circ
[
chn
],
LSEEK_CIRC_VALID
,
SEEK_END
)
<
0
))
{
D3
(
fprintf
(
debug_file
,
"2: state->cirbuf_rp=0x%x
\n
"
,
state
->
cirbuf_rp
[
chn
]));
D3
(
fprintf
(
debug_file
,
"2: state->cirbuf_rp=0x%x
\n
"
,
state
->
cirbuf_rp
[
chn
]));
/* In "greedy" mode try to save as many frames from the circbuf as possible */
/* In "greedy" mode try to save as many frames from the circbuf as possible */
...
@@ -659,6 +660,7 @@ int sendImageFrame(camogm_state *state)
...
@@ -659,6 +660,7 @@ int sendImageFrame(camogm_state *state)
state
->
packetchunks
[
state
->
chunk_index
].
bytes
=
state
->
jpeg_len
;
state
->
packetchunks
[
state
->
chunk_index
].
bytes
=
state
->
jpeg_len
;
state
->
packetchunks
[
state
->
chunk_index
++
].
chunk
=
(
unsigned
char
*
)
&
ccam_dma_buf
[
state
->
port_num
][
state
->
cirbuf_rp
[
port
]
>>
2
];
state
->
packetchunks
[
state
->
chunk_index
++
].
chunk
=
(
unsigned
char
*
)
&
ccam_dma_buf
[
state
->
port_num
][
state
->
cirbuf_rp
[
port
]
>>
2
];
}
}
D3
(
fprintf
(
debug_file
,
"
\t
cirbuf_rp = 0x%x
\t
"
,
state
->
cirbuf_rp
[
port
]));
D3
(
fprintf
(
debug_file
,
"_12_"
));
D3
(
fprintf
(
debug_file
,
"_12_"
));
state
->
packetchunks
[
state
->
chunk_index
].
bytes
=
2
;
state
->
packetchunks
[
state
->
chunk_index
].
bytes
=
2
;
state
->
packetchunks
[
state
->
chunk_index
++
].
chunk
=
(
unsigned
char
*
)
trailer
;
state
->
packetchunks
[
state
->
chunk_index
++
].
chunk
=
(
unsigned
char
*
)
trailer
;
...
@@ -681,6 +683,7 @@ int sendImageFrame(camogm_state *state)
...
@@ -681,6 +683,7 @@ int sendImageFrame(camogm_state *state)
// advance frame pointer
// advance frame pointer
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
);
D3
(
fprintf
(
debug_file
,
"
\t
compressed frame number: %li
\t
"
,
lseek
(
state
->
fd_circ
[
port
],
LSEEK_CIRC_GETFRAME
,
SEEK_END
)));
// optionally save it to global read pointer (i.e. for debugging with imgsrv "/pointers")
// optionally save it to global read pointer (i.e. for debugging with imgsrv "/pointers")
if
(
state
->
save_gp
)
lseek
(
state
->
fd_circ
[
port
],
LSEEK_CIRC_SETP
,
SEEK_END
);
if
(
state
->
save_gp
)
lseek
(
state
->
fd_circ
[
port
],
LSEEK_CIRC_SETP
,
SEEK_END
);
D3
(
fprintf
(
debug_file
,
"_15_
\n
"
));
D3
(
fprintf
(
debug_file
,
"_15_
\n
"
));
...
@@ -689,6 +692,7 @@ int sendImageFrame(camogm_state *state)
...
@@ -689,6 +692,7 @@ int sendImageFrame(camogm_state *state)
}
else
if
(
state
->
frames_skip
<
0
)
{
}
else
if
(
state
->
frames_skip
<
0
)
{
state
->
frames_skip_left
[
port
]
+=
-
(
state
->
frames_skip
);
state
->
frames_skip_left
[
port
]
+=
-
(
state
->
frames_skip
);
}
}
D3
(
fprintf
(
debug_file
,
"cirbuf_rp to next frame = 0x%x
\n
"
,
state
->
cirbuf_rp
[
port
]));
return
0
;
return
0
;
}
}
...
...
src/camogm_test.c
View file @
4e936992
/** @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
/** Needed for O_DIRECT */
#define _GNU_SOURCE
#include <stdbool.h>
#include <stdbool.h>
#include <unistd.h>
#include <unistd.h>
...
@@ -17,6 +19,7 @@
...
@@ -17,6 +19,7 @@
#include <ctype.h>
#include <ctype.h>
#include <signal.h>
#include <signal.h>
#include <elphel/ahci_cmd.h>
#include <elphel/ahci_cmd.h>
#include <pthread.h>
#include "camogm.h"
#include "camogm.h"
#include "camogm_read.h"
#include "camogm_read.h"
...
@@ -82,7 +85,16 @@ const char *circbufFileNames[] = {DEV393_PATH(DEV393_CIRCBUF0), DEV393_PATH(DEV3
...
@@ -82,7 +85,16 @@ const char *circbufFileNames[] = {DEV393_PATH(DEV393_CIRCBUF0), DEV393_PATH(DEV3
unsigned
long
*
ccam_dma_buf
[
SENSOR_PORTS
];
unsigned
long
*
ccam_dma_buf
[
SENSOR_PORTS
];
int
debug_level
;
int
debug_level
;
FILE
*
debug_file
;
FILE
*
debug_file
;
static
volatile
bool
keep_running
=
true
;
static
volatile
bool
keep_running
=
true
;
// global flag for stopping threads
pthread_mutex_t
writer_mutex
=
PTHREAD_MUTEX_INITIALIZER
;
pthread_mutex_t
writer_block
=
PTHREAD_MUTEX_INITIALIZER
;
pthread_cond_t
writer_cond
=
PTHREAD_COND_INITIALIZER
;
pthread_cond_t
main_cond
=
PTHREAD_COND_INITIALIZER
;
char
block_dev
[
ELPHEL_PATH_MAX
];
bool
block_dev_op
=
true
;
// write data from writer thread instead of sending direct commands to driver
unsigned
long
*
writer_data_ptr
=
NULL
;
// pointer to next data block in circbuf to be written from writer thread
int
writer_data_len
;
// size of next data block to be written from writer thread
bool
main_op
=
true
;
// allow main thread to proceed with data preparing
int
open_files
(
camogm_state
*
state
);
int
open_files
(
camogm_state
*
state
);
void
clean_up
(
camogm_state
*
state
);
void
clean_up
(
camogm_state
*
state
);
...
@@ -125,7 +137,7 @@ void camogm_init(camogm_state *state, char *pipe_name, uint16_t port_num)
...
@@ -125,7 +137,7 @@ void camogm_init(camogm_state *state, char *pipe_name, uint16_t port_num)
memset
(
state
,
0
,
sizeof
(
camogm_state
));
memset
(
state
,
0
,
sizeof
(
camogm_state
));
camogm_reset
(
state
);
// sets state->buf_overruns =- 1
camogm_reset
(
state
);
// sets state->buf_overruns =- 1
state
->
serialno
=
ipser
[
0
];
state
->
serialno
=
ipser
[
0
];
debug_file
=
std
err
;
debug_file
=
std
out
;
camogm_debug_level
(
DEFAULT_DEBUG_LVL
);
camogm_debug_level
(
DEFAULT_DEBUG_LVL
);
strcpy
(
state
->
debug_name
,
"stderr"
);
strcpy
(
state
->
debug_name
,
"stderr"
);
state
->
exif
=
DEFAULT_EXIF
;
state
->
exif
=
DEFAULT_EXIF
;
...
@@ -187,7 +199,7 @@ int open_files(camogm_state *state)
...
@@ -187,7 +199,7 @@ int open_files(camogm_state *state)
clean_up
(
state
);
clean_up
(
state
);
return
-
3
;
return
-
3
;
}
else
{
}
else
{
D0
(
fprintf
(
debug_file
,
"successfully mmap cirbuf region
\n
"
));
D0
(
fprintf
(
debug_file
,
"successfully mmap cirbuf region
, ptr = %p
\n
"
,
(
void
*
)
ccam_dma_buf
[
port
]
));
}
}
return
ret
;
return
ret
;
...
@@ -207,7 +219,20 @@ int sendImageFrame(camogm_state *state)
...
@@ -207,7 +219,20 @@ int sendImageFrame(camogm_state *state)
fdata
.
cmd
|=
DRV_CMD_EXIF
;
fdata
.
cmd
|=
DRV_CMD_EXIF
;
}
}
fdata
.
cmd
|=
DRV_CMD_WRITE_TEST
;
fdata
.
cmd
|=
DRV_CMD_WRITE_TEST
;
ret
=
write
(
state
->
rawdev
.
sysfs_fd
,
&
fdata
,
sizeof
(
struct
frame_data
));
if
(
!
block_dev_op
)
{
ret
=
write
(
state
->
rawdev
.
sysfs_fd
,
&
fdata
,
sizeof
(
struct
frame_data
));
}
else
{
// write to block device, but not using direct driver commands
pthread_mutex_lock
(
&
writer_mutex
);
while
(
!
main_op
)
pthread_cond_wait
(
&
main_cond
,
&
writer_mutex
);
D0
(
fprintf
(
debug_file
,
"Update data pointer
\n
"
));
writer_data_ptr
=
ccam_dma_buf
[
port
]
+
state
->
cirbuf_rp
[
port
];
writer_data_len
=
state
->
jpeg_len
;
main_op
=
false
;
pthread_cond_signal
(
&
writer_cond
);
pthread_mutex_unlock
(
&
writer_mutex
);
}
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
// D0(fprintf(debug_file, "Can not pass IO vector to driver (driver may be busy): %s\r", strerror(errno)));
// D0(fprintf(debug_file, "Can not pass IO vector to driver (driver may be busy): %s\r", strerror(errno)));
ret
=
errno
;
ret
=
errno
;
...
@@ -668,7 +693,9 @@ int listener_loop(camogm_state *state, struct dd_params *dd_params)
...
@@ -668,7 +693,9 @@ int listener_loop(camogm_state *state, struct dd_params *dd_params)
seconds
=
difftime
(
now
,
dd_params
->
start_time
);
seconds
=
difftime
(
now
,
dd_params
->
start_time
);
if
(
seconds
>
0
)
if
(
seconds
>
0
)
wr_speed
=
mb_written
/
(
unsigned
long
)
seconds
;
wr_speed
=
mb_written
/
(
unsigned
long
)
seconds
;
D0
(
fprintf
(
debug_file
,
"
\r
%lu MiB written, number of counts left: %04lu, average speed: %u MB/s"
,
// D0(fprintf(debug_file, "\r%lu MiB written, number of counts left: %04lu, average speed: %u MB/s",
// mb_written, dd_params->block_count, wr_speed));
D0
(
fprintf
(
debug_file
,
"%lu MiB written, number of counts left: %04lu, average speed: %u MB/s
\n
"
,
mb_written
,
dd_params
->
block_count
,
wr_speed
));
mb_written
,
dd_params
->
block_count
,
wr_speed
));
read_stat
(
mb_written
,
state
->
path
);
read_stat
(
mb_written
,
state
->
path
);
}
else
{
}
else
{
...
@@ -749,6 +776,64 @@ static void start_test(camogm_state *state, const unsigned long max_cntr, const
...
@@ -749,6 +776,64 @@ static void start_test(camogm_state *state, const unsigned long max_cntr, const
close
(
fd
);
close
(
fd
);
}
}
// writer thread
void
*
writer
(
void
*
params
)
{
int
fd
;
int
ret
=
0
;
bool
process
=
true
;
unsigned
char
*
tmp_buff
;
size_t
tmp_buff_sz
=
1048576
;
ret
=
posix_memalign
((
void
**
)
&
tmp_buff
,
sysconf
(
_SC_PAGE_SIZE
),
tmp_buff_sz
);
if
(
ret
==
0
)
{
printf
(
"Aligned buffer allocated, ptr = %p
\n
"
,
tmp_buff
);
}
else
{
printf
(
"Can not allocate aligned buffer
\n
"
);
return
(
void
*
)
-
1
;
}
memset
(
tmp_buff
,
1
,
tmp_buff_sz
);
// open block device for writing
if
((
fd
=
open
(
block_dev
,
O_WRONLY
))
<
0
)
{
// if ((fd = open(block_dev, O_WRONLY | O_DIRECT)) < 0) {
// if ((fd = open("/mnt/sda1/thread_write.bin", O_CREAT | O_WRONLY)) < 0) {
// if ((fd = open("/mnt/sda1/thread_write.bin", O_CREAT | O_WRONLY | O_DIRECT)) < 0) {
printf
(
"Can not open block device %s: %s
\n
"
,
block_dev
,
strerror
(
errno
));
return
(
void
*
)
-
1
;
}
else
{
printf
(
"Block device %s is opened from writer thread
\n
"
,
block_dev
);
}
// start recording
pthread_mutex_lock
(
&
writer_mutex
);
while
(
process
&&
keep_running
)
{
while
((
writer_data_ptr
==
NULL
)
&&
keep_running
)
pthread_cond_wait
(
&
writer_cond
,
&
writer_mutex
);
if
(
writer_data_ptr
!=
NULL
)
{
printf
(
"Emulate write, ptr = %p, size = %i
\n
"
,
(
void
*
)
writer_data_ptr
,
writer_data_len
);
// ret = write(fd, tmp_buff, tmp_buff_sz);
ret
=
write
(
fd
,
writer_data_ptr
,
writer_data_len
);
if
(
ret
<
0
)
{
printf
(
"Error during recording: %s
\n
"
,
strerror
(
errno
));
process
=
false
;
// exit from main thread also
keep_running
=
false
;
}
printf
(
"%i bytes written
\n
"
,
ret
);
writer_data_ptr
=
NULL
;
// wait while data will be ready
main_op
=
true
;
pthread_cond_signal
(
&
main_cond
);
}
}
pthread_mutex_unlock
(
&
writer_mutex
);
// thread is terminating, clean up
close
(
fd
);
printf
(
"Exit from writer
\n
"
);
return
NULL
;
}
int
main
(
int
argc
,
char
*
argv
[])
int
main
(
int
argc
,
char
*
argv
[])
{
{
const
char
usage
[]
=
"This program is intended for disk write tests
\n
"
\
const
char
usage
[]
=
"This program is intended for disk write tests
\n
"
\
...
@@ -780,6 +865,8 @@ int main(int argc, char *argv[])
...
@@ -780,6 +865,8 @@ int main(int argc, char *argv[])
struct
dd_params
dd_params
=
{
0
};
struct
dd_params
dd_params
=
{
0
};
struct
range
range
;
struct
range
range
;
struct
range
disk_range
;
struct
range
disk_range
;
pthread_t
writer_thread
;
pthread_attr_t
attr
;
if
((
argc
<
2
)
||
(
argv
[
1
][
1
]
==
'-'
))
{
if
((
argc
<
2
)
||
(
argv
[
1
][
1
]
==
'-'
))
{
printf
(
usage
,
argv
[
0
],
argv
[
0
]);
printf
(
usage
,
argv
[
0
],
argv
[
0
]);
...
@@ -790,6 +877,7 @@ int main(int argc, char *argv[])
...
@@ -790,6 +877,7 @@ int main(int argc, char *argv[])
case
'd'
:
case
'd'
:
// set path to disk under test
// set path to disk under test
strncpy
(
disk_path
,
(
const
char
*
)
optarg
,
ELPHEL_PATH_MAX
-
1
);
strncpy
(
disk_path
,
(
const
char
*
)
optarg
,
ELPHEL_PATH_MAX
-
1
);
strncpy
(
block_dev
,
(
const
char
*
)
optarg
,
ELPHEL_PATH_MAX
-
1
);
break
;
break
;
case
'n'
:
case
'n'
:
strncpy
(
pipe_name_str
,
(
const
char
*
)
optarg
,
ELPHEL_PATH_MAX
-
1
);
strncpy
(
pipe_name_str
,
(
const
char
*
)
optarg
,
ELPHEL_PATH_MAX
-
1
);
...
@@ -846,6 +934,14 @@ int main(int argc, char *argv[])
...
@@ -846,6 +934,14 @@ int main(int argc, char *argv[])
camogm_init
(
&
sstate
,
pipe_name_str
,
port_num
);
camogm_init
(
&
sstate
,
pipe_name_str
,
port_num
);
if
(
!
test_mode
)
{
if
(
!
test_mode
)
{
// spawn writer thread first
pthread_attr_init
(
&
attr
);
ret
=
pthread_create
(
&
writer_thread
,
&
attr
,
writer
,
NULL
);
if
(
ret
<
0
)
{
printf
(
"Can not spawn new thread: %s
\n
"
,
strerror
(
errno
));
return
ret
;
}
ret
=
open_files
(
&
sstate
);
ret
=
open_files
(
&
sstate
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
ret
;
return
ret
;
...
@@ -871,6 +967,12 @@ int main(int argc, char *argv[])
...
@@ -871,6 +967,12 @@ int main(int argc, char *argv[])
clean_up
(
&
sstate
);
clean_up
(
&
sstate
);
ret
=
EXIT_FAILURE
;
ret
=
EXIT_FAILURE
;
}
}
printf
(
"Exit from main
\n
"
);
pthread_mutex_lock
(
&
writer_mutex
);
keep_running
=
false
;
pthread_cond_signal
(
&
writer_cond
);
pthread_mutex_unlock
(
&
writer_mutex
);
pthread_join
(
writer_thread
,
NULL
);
clean_up
(
&
sstate
);
clean_up
(
&
sstate
);
}
else
{
}
else
{
if
(
dd_params
.
block_size
!=
0
)
{
if
(
dd_params
.
block_size
!=
0
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment