diff options
-rw-r--r-- | cli.c | 25 | ||||
-rw-r--r-- | event.c | 16 | ||||
-rw-r--r-- | event.h | 5 | ||||
-rw-r--r-- | ipecamera/ipecamera.c | 7 | ||||
-rw-r--r-- | pcilib.h | 8 |
5 files changed, 57 insertions, 4 deletions
@@ -127,6 +127,7 @@ typedef enum { OPT_RUN_TIME, OPT_FORMAT, OPT_BUFFER, + OPT_THREADS, OPT_LIST_DMA, OPT_LIST_DMA_BUFFERS, OPT_READ_DMA_BUFFER, @@ -167,6 +168,7 @@ static struct option long_options[] = { {"trigger-time", required_argument, 0, OPT_TRIGGER_TIME }, {"format", required_argument, 0, OPT_FORMAT }, {"buffer", optional_argument, 0, OPT_BUFFER }, + {"threads", optional_argument, 0, OPT_THREADS }, {"start-dma", required_argument, 0, OPT_START_DMA }, {"stop-dma", optional_argument, 0, OPT_STOP_DMA }, {"list-dma-engines", no_argument, 0, OPT_LIST_DMA }, @@ -258,6 +260,7 @@ void Usage(int argc, char *argv[], const char *format, ...) { " add_header - Prefix events with 256 bit header\n" //" ringfs - Write to RingFS\n" " --buffer [size] - Request data buffering, size in MB\n" +" --threads [num] - Allow multithreaded processing\n" "\n" " DMA Options:\n" " --multipacket - Read multiple packets\n" @@ -1281,7 +1284,7 @@ void *Monitor(void *user) { return NULL; } -int TriggerAndGrab(pcilib_t *handle, GRAB_MODE grab_mode, const char *evname, const char *data_type, size_t num, size_t run_time, size_t trigger_time, pcilib_timeout_t timeout, PARTITION partition, FORMAT format, size_t buffer_size, FILE *ofile) { +int TriggerAndGrab(pcilib_t *handle, GRAB_MODE grab_mode, const char *evname, const char *data_type, size_t num, size_t run_time, size_t trigger_time, pcilib_timeout_t timeout, PARTITION partition, FORMAT format, size_t buffer_size, size_t threads, FILE *ofile) { int err; GRABContext ctx; // void *data = NULL; @@ -1346,7 +1349,10 @@ int TriggerAndGrab(pcilib_t *handle, GRAB_MODE grab_mode, const char *evname, co if (flags&PCILIB_EVENT_FLAG_RAW_DATA_ONLY) { pcilib_configure_rawdata_callback(handle, &raw_data, NULL); } - + + if (flags&PCILIB_EVENT_FLAG_PREPROCESS) { + pcilib_configure_preprocessing_threads(handle, threads); + } if (grab_mode&GRAB_MODE_TRIGGER) { if (trigger_time) { @@ -1903,6 +1909,7 @@ int main(int argc, char **argv) { size_t trigger_time = 0; size_t run_time = 0; size_t buffer = 0; + size_t threads = 1; FORMAT format = FORMAT_RAW; PARTITION partition = PARTITION_UNKNOWN; FLAGS flags = 0; @@ -2227,6 +2234,18 @@ int main(int argc, char **argv) { buffer -= 128 + buffer/16; } break; + case OPT_THREADS: + if (optarg) num_offset = optarg; + else if ((optind < argc)&&(argv[optind][0] != '-')) num_offset = argv[optind++]; + else num_offset = NULL; + + if (num_offset) { + if ((!isnumber(num_offset))||(sscanf(num_offset, "%zu", &threads) != 1)) + Usage(argc, argv, "Invalid threads number is specified (%s)", num_offset); + } else { + threads = 0; + } + break; case OPT_FORMAT: if (!strcasecmp(optarg, "add_header")) format = FORMAT_HEADER; else if (!strcasecmp(optarg, "ringfs")) format = FORMAT_RINGFS; @@ -2454,7 +2473,7 @@ int main(int argc, char **argv) { pcilib_reset(handle); break; case MODE_GRAB: - TriggerAndGrab(handle, grab_mode, event, data_type, size, run_time, trigger_time, timeout, partition, format, buffer, ofile); + TriggerAndGrab(handle, grab_mode, event, data_type, size, run_time, trigger_time, timeout, partition, format, buffer, threads, ofile); break; case MODE_LIST_DMA: ListDMA(handle, fpga_device, model_info); @@ -121,6 +121,22 @@ int pcilib_configure_autostop(pcilib_t *ctx, size_t max_events, pcilib_timeout_t return 0; } +int pcilib_configure_preprocessing_threads(pcilib_t *ctx, size_t max_threads) { + pcilib_event_api_description_t *api; + + pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); + + api = model_info->event_api; + if (!api) { + pcilib_error("Event API is not supported by the selected model"); + return PCILIB_ERROR_NOTSUPPORTED; + } + + ctx->event_ctx->params.parallel.max_threads = max_threads; + + return 0; +} + int pcilib_start(pcilib_t *ctx, pcilib_event_t event_mask, pcilib_event_flags_t flags) { pcilib_event_api_description_t *api; @@ -47,8 +47,13 @@ typedef struct { } pcilib_rawdata_parameters_t; typedef struct { + size_t max_threads; +} pcilib_parallel_parameters_t; + +typedef struct { pcilib_autostop_parameters_t autostop; pcilib_rawdata_parameters_t rawdata; + pcilib_parallel_parameters_t parallel; } pcilib_event_parameters_t; struct pcilib_event_context_s { diff --git a/ipecamera/ipecamera.c b/ipecamera/ipecamera.c index c170174..d963494 100644 --- a/ipecamera/ipecamera.c +++ b/ipecamera/ipecamera.c @@ -407,12 +407,17 @@ int ipecamera_start(pcilib_context_t *vctx, pcilib_event_t event_mask, pcilib_ev if (flags&PCILIB_EVENT_FLAG_PREPROCESS) { ctx->n_preproc = pcilib_get_cpu_count(); + + // it would be greate to detect hyperthreading cores and ban them switch (ctx->n_preproc) { case 1: break; case 2-3: ctx->n_preproc -= 1; break; default: ctx->n_preproc -= 2; break; } - + + if ((vctx->params.parallel.max_threads)&&(vctx->params.parallel.max_threads < ctx->n_preproc)) + ctx->n_preproc = vctx->params.parallel.max_threads; + ctx->preproc = (ipecamera_preprocessor_t*)malloc(ctx->n_preproc * sizeof(ipecamera_preprocessor_t)); if (!ctx->preproc) { ipecamera_stop(vctx, PCILIB_EVENT_FLAGS_DEFAULT); @@ -332,6 +332,14 @@ int pcilib_configure_autostop(pcilib_t *ctx, size_t max_events, pcilib_timeout_t */ int pcilib_configure_rawdata_callback(pcilib_t *ctx, pcilib_event_rawdata_callback_t callback, void *user); +/* + * Configures maximal number of preprocessing threads. Actual amount of threads + * may be bigger. For instance, additionaly a real-time reader thread will be + * executed for most of hardware + */ +int pcilib_configure_preprocessing_threads(pcilib_t *ctx, size_t max_threads); + + int pcilib_start(pcilib_t *ctx, pcilib_event_t event_mask, pcilib_event_flags_t flags); int pcilib_stop(pcilib_t *ctx, pcilib_event_flags_t flags); |