mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-05-12 11:18:11 -07:00
move thread scheduler threads.c, move opencl engine in opencl.c, minor fixes
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -40,6 +40,452 @@ bool plat_dev_enabled(unsigned int id, unsigned int *sel, unsigned int cnt, unsi
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int get_smallest_profile (compute_platform_ctx_t *cd_ctx, size_t ocl_platform_cnt)
|
||||
{
|
||||
unsigned int profile = 0xff;
|
||||
|
||||
size_t x = 0, y = 0;
|
||||
|
||||
for (x = 0; x < ocl_platform_cnt; x++) {
|
||||
if (!cd_ctx[x].selected) continue;
|
||||
|
||||
for (y = 0; y < cd_ctx[x].device_cnt; y++) {
|
||||
if (!cd_ctx[x].device[y].selected) continue;
|
||||
|
||||
#if DEBUGME > 1
|
||||
printf("[debug] Initial profile for device %zu: %d\n", z, cd_ctx[x].device[y].profile);
|
||||
#endif
|
||||
|
||||
// with same devices will be selected the best
|
||||
// but for different devices in the same platform we need the worst for now (todo)
|
||||
if (cd_ctx[x].device[y].profile < profile) profile = cd_ctx[x].device[y].profile;
|
||||
}
|
||||
}
|
||||
|
||||
// at worst, set profile to 0
|
||||
if (profile > 10) profile = 0;
|
||||
|
||||
return profile;
|
||||
}
|
||||
|
||||
int discoverDevices(unsigned int profile_selected, uint32_t device_types_selected, cl_uint *platform_detected_cnt, size_t *selected_platforms_cnt, size_t *selected_devices_cnt, compute_platform_ctx_t **cd_ctx, unsigned int *plat_sel, unsigned int plat_cnt, unsigned int *dev_sel, unsigned int dev_cnt, bool verbose, bool show)
|
||||
{
|
||||
int err = 0;
|
||||
unsigned int ocl_platform_max = MAX_OPENCL_DEVICES; // 16
|
||||
cl_uint ocl_platform_cnt;
|
||||
|
||||
cl_platform_id *ocl_platforms = (cl_platform_id *) calloc(ocl_platform_max, sizeof(cl_platform_id));
|
||||
if (!ocl_platforms) {
|
||||
printf("Error: calloc (ocl_platforms) failed (%d): %s\n", errno, strerror(errno));
|
||||
return -2;
|
||||
}
|
||||
|
||||
// enum platforms
|
||||
err = clGetPlatformIDs(ocl_platform_max, ocl_platforms, &ocl_platform_cnt);
|
||||
if (err != CL_SUCCESS) {
|
||||
printf("Error: clGetPlatformIDs() failed (%d)\n", err);
|
||||
free (ocl_platforms);
|
||||
return -3;
|
||||
}
|
||||
|
||||
if (ocl_platform_cnt == 0) {
|
||||
printf("No platforms found, exit\n");
|
||||
free (ocl_platforms);
|
||||
return -4;
|
||||
}
|
||||
|
||||
// allocate memory to hold info about platforms/devices
|
||||
*cd_ctx = (compute_platform_ctx_t *) calloc(ocl_platform_cnt, sizeof(compute_platform_ctx_t));
|
||||
if (*cd_ctx == NULL) {
|
||||
printf("Error: calloc (compute_platform_ctx_t) failed (%d): %s\n", errno, strerror(errno));
|
||||
free (ocl_platforms);
|
||||
return -5;
|
||||
}
|
||||
|
||||
cl_platform_info ocl_platforms_info[3] = { CL_PLATFORM_NAME, CL_PLATFORM_VENDOR, CL_PLATFORM_VERSION };
|
||||
unsigned int ocl_platforms_info_cnt = sizeof(ocl_platforms_info) / sizeof(cl_platform_info);
|
||||
|
||||
cl_device_info ocl_devices_info[8] = { CL_DEVICE_TYPE, CL_DEVICE_NAME, CL_DEVICE_VERSION, CL_DRIVER_VERSION, CL_DEVICE_VENDOR, CL_DEVICE_LOCAL_MEM_TYPE, CL_DEVICE_MAX_WORK_ITEM_SIZES, CL_DEVICE_MAX_COMPUTE_UNITS };
|
||||
unsigned int ocl_devices_info_cnt = sizeof(ocl_devices_info) / sizeof(cl_device_info);
|
||||
|
||||
unsigned int info_idx = 0;
|
||||
size_t tmp_len = 0;
|
||||
char *tmp_buf = NULL;
|
||||
|
||||
unsigned int global_device_id = 0;
|
||||
|
||||
if (verbose) printf("- Found %u OpenCL Platform(s)\n", ocl_platform_cnt);
|
||||
|
||||
for (cl_uint platform_idx = 0; platform_idx < ocl_platform_cnt; platform_idx++) {
|
||||
(*cd_ctx)[platform_idx].platform_id = ocl_platforms[platform_idx];
|
||||
(*cd_ctx)[platform_idx].selected = plat_dev_enabled(platform_idx, plat_sel, plat_cnt, 0, 0);
|
||||
|
||||
if ((*cd_ctx)[platform_idx].selected) (*selected_platforms_cnt)++;
|
||||
|
||||
if (verbose) printf("\n-- Platform ID: %d\n", platform_idx + 1);
|
||||
|
||||
for (info_idx = 0; info_idx < ocl_platforms_info_cnt; info_idx++) {
|
||||
cl_platform_info ocl_info = ocl_platforms_info[info_idx];
|
||||
|
||||
err = clGetPlatformInfo((*cd_ctx)[platform_idx].platform_id, ocl_info, 0, NULL, &tmp_len);
|
||||
if (err != CL_SUCCESS) {
|
||||
printf("Error: clGetPlatformInfo(param size) failed (%d)\n", err);
|
||||
free (*cd_ctx);
|
||||
free (ocl_platforms);
|
||||
return -6;
|
||||
}
|
||||
|
||||
if (tmp_len > 0) {
|
||||
if (!(tmp_buf = (char *) calloc(tmp_len, sizeof(char)))) {
|
||||
printf("Error: calloc (ocl_info %u) failed (%d): %s\n", info_idx, errno, strerror(errno));
|
||||
free (*cd_ctx);
|
||||
free (ocl_platforms);
|
||||
return -7;
|
||||
}
|
||||
|
||||
err = clGetPlatformInfo((*cd_ctx)[platform_idx].platform_id, ocl_info, tmp_len, tmp_buf, 0);
|
||||
if (err != CL_SUCCESS) {
|
||||
printf("Error: clGetPlatformInfo(param) failed (%d)\n", err);
|
||||
free (tmp_buf);
|
||||
free (*cd_ctx);
|
||||
free (ocl_platforms);
|
||||
return -8;
|
||||
}
|
||||
} else {
|
||||
tmp_len = 4;
|
||||
if (!(tmp_buf = (char *) calloc(tmp_len, sizeof(char)))) {
|
||||
printf("Error: calloc (ocl_info %u) failed (%d): %s\n", info_idx, errno, strerror(errno));
|
||||
free (*cd_ctx);
|
||||
free (ocl_platforms);
|
||||
return -7;
|
||||
}
|
||||
|
||||
strncpy(tmp_buf, "N/A\0", tmp_len);
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
const char *tmp_info_desc = (info_idx == 0) ? "Name" : (info_idx == 1) ? "Vendor" : "Version";
|
||||
|
||||
printf("%14s: %s\n", tmp_info_desc, tmp_buf);
|
||||
}
|
||||
|
||||
switch (info_idx) {
|
||||
case 0:
|
||||
strncpy((*cd_ctx)[platform_idx].name, tmp_buf, tmp_len < 0xff ? tmp_len : 0xff - 1);
|
||||
break;
|
||||
case 1:
|
||||
strncpy((*cd_ctx)[platform_idx].vendor, tmp_buf, tmp_len < 0x40 ? tmp_len : 0x40 - 1);
|
||||
break;
|
||||
case 2:
|
||||
strncpy((*cd_ctx)[platform_idx].version, tmp_buf, tmp_len < 0x40 ? tmp_len : 0x40 - 1);
|
||||
break;
|
||||
}
|
||||
|
||||
if (info_idx == 1) {
|
||||
if (!strncmp(tmp_buf, "NVIDIA", 6)) (*cd_ctx)[platform_idx].is_nv = true;
|
||||
else if (!strncmp(tmp_buf, "Apple", 5)) { (*cd_ctx)[platform_idx].is_apple = true; (*cd_ctx)[platform_idx].warning = true; }
|
||||
else if (!strncmp(tmp_buf, "Intel", 5)) (*cd_ctx)[platform_idx].is_intel = true;
|
||||
else if (!strncmp(tmp_buf, "The pocl project", 16)) (*cd_ctx)[platform_idx].is_pocl = true;
|
||||
}
|
||||
|
||||
free (tmp_buf);
|
||||
}
|
||||
|
||||
if (!show && verbose) {
|
||||
printf("%14s: %s\n", "Selected", ((*cd_ctx)[platform_idx].selected) ? "yes" : "no");
|
||||
if ((*cd_ctx)[platform_idx].warning) printf("\n%14s: performance will not be optimal using this platform\n\n", "=====> Warning");
|
||||
}
|
||||
|
||||
// enum devices with this platform
|
||||
unsigned int ocl_device_cnt = 0;
|
||||
unsigned int ocl_device_max = MAX_OPENCL_DEVICES;
|
||||
|
||||
cl_device_id *ocl_devices = (cl_device_id *) calloc(ocl_device_max, sizeof(cl_device_id));
|
||||
if (!ocl_devices) {
|
||||
printf("Error: calloc (ocl_devices) failed (%d): %s\n", errno, strerror(errno));
|
||||
free (*cd_ctx);
|
||||
free (ocl_platforms);
|
||||
return -7;
|
||||
}
|
||||
|
||||
err = clGetDeviceIDs((*cd_ctx)[platform_idx].platform_id, CL_DEVICE_TYPE_ALL, ocl_device_max, ocl_devices, &ocl_device_cnt);
|
||||
if (ocl_device_cnt == 0) {
|
||||
if (device_types_selected == CL_DEVICE_TYPE_ALL) printf("No device(s) available with platform id %d\n", platform_idx);
|
||||
(*cd_ctx)[platform_idx].device_cnt = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (err != CL_SUCCESS) {
|
||||
printf("Error: clGetDeviceIDs(cnt) failed (%d)\n", err);
|
||||
free (ocl_devices);
|
||||
free (*cd_ctx);
|
||||
free (ocl_platforms);
|
||||
return -9;
|
||||
}
|
||||
|
||||
if (verbose) printf("%14s: %u\n", "Device(s)", ocl_device_cnt);
|
||||
|
||||
(*cd_ctx)[platform_idx].device_cnt = ocl_device_cnt;
|
||||
|
||||
for (unsigned int device_idx = 0; device_idx < ocl_device_cnt; device_idx++) {
|
||||
memset(&(*cd_ctx)[platform_idx].device[device_idx], 0, sizeof(compute_device_ctx_t));
|
||||
cl_device_id ocl_device = ocl_devices[device_idx];
|
||||
(*cd_ctx)[platform_idx].device[device_idx].platform_id = (*cd_ctx)[platform_idx].platform_id;
|
||||
|
||||
if (verbose) printf("---- * ID: %u\n", global_device_id + 1);
|
||||
|
||||
for (info_idx = 0; info_idx < ocl_devices_info_cnt; info_idx++) {
|
||||
cl_device_info ocl_dev_info = ocl_devices_info[info_idx];
|
||||
|
||||
if (info_idx == 0) {
|
||||
cl_device_type device_type;
|
||||
|
||||
err = clGetDeviceInfo(ocl_device, ocl_dev_info, sizeof(cl_device_type), &device_type, 0);
|
||||
if (err != CL_SUCCESS) {
|
||||
printf("Error: clGetDeviceInfo(device_type) failed (%d)\n", err);
|
||||
free (ocl_devices);
|
||||
free (*cd_ctx);
|
||||
free (ocl_platforms);
|
||||
return -10;
|
||||
}
|
||||
|
||||
if (device_type & CL_DEVICE_TYPE_GPU) (*cd_ctx)[platform_idx].device[device_idx].is_gpu = 1;
|
||||
else if ((device_type & CL_DEVICE_TYPE_CPU) && (*cd_ctx)[platform_idx].is_pocl) {
|
||||
(*cd_ctx)[platform_idx].device[device_idx].profile = (profile_selected > 1) ? 0 : profile_selected;
|
||||
}
|
||||
|
||||
if (verbose) printf("%14s: %s\n", "Device Type", (device_type & CL_DEVICE_TYPE_GPU) ? "GPU" : (device_type & CL_DEVICE_TYPE_CPU) ? "CPU" : "Other");
|
||||
|
||||
(*cd_ctx)[platform_idx].device[device_idx].selected = plat_dev_enabled(global_device_id, dev_sel, dev_cnt, (unsigned int) device_type, device_types_selected);
|
||||
global_device_id++;
|
||||
if ((*cd_ctx)[platform_idx].device[device_idx].selected) (*selected_devices_cnt)++;
|
||||
continue;
|
||||
} else if (info_idx == 5) {
|
||||
cl_device_local_mem_type local_mem_type;
|
||||
|
||||
err = clGetDeviceInfo(ocl_device, ocl_dev_info, sizeof(cl_device_local_mem_type), &local_mem_type, 0);
|
||||
if (err != CL_SUCCESS) {
|
||||
printf("Error: clGetDeviceInfo(local_mem_type) failed (%d)\n", err);
|
||||
free (ocl_devices);
|
||||
free (*cd_ctx);
|
||||
free (ocl_platforms);
|
||||
return -10;
|
||||
}
|
||||
|
||||
if (local_mem_type == CL_LOCAL || local_mem_type == CL_GLOBAL) {
|
||||
if (verbose) printf("%14s: %s\n", "Local Mem Type", (local_mem_type == CL_LOCAL) ? "Local" : "Global");
|
||||
if ((*cd_ctx)[platform_idx].is_apple) {
|
||||
if (strncmp((*cd_ctx)[platform_idx].device[device_idx].vendor, "Intel", 5) != 0) {
|
||||
(*cd_ctx)[platform_idx].device[device_idx].have_local_memory = true;
|
||||
|
||||
if ((*cd_ctx)[platform_idx].device[device_idx].is_gpu) {
|
||||
if (profile_selected > 2) (*cd_ctx)[platform_idx].device[device_idx].profile = PROFILE_DEFAULT; // Apple-Intel GPU's
|
||||
} else {
|
||||
if (profile_selected > 3) (*cd_ctx)[platform_idx].device[device_idx].profile = PROFILE_DEFAULT; // Apple-Intel CPU's
|
||||
}
|
||||
}
|
||||
} else if ((*cd_ctx)[platform_idx].is_nv) {
|
||||
(*cd_ctx)[platform_idx].device[device_idx].have_local_memory = true;
|
||||
}
|
||||
} else {
|
||||
if (verbose) printf("%14s: None\n", "Local Mem Type");
|
||||
}
|
||||
|
||||
if (verbose) printf("%14s: %s\n", "Local Mem Opt", ((*cd_ctx)[platform_idx].device[device_idx].have_local_memory) ? "yes" : "no");
|
||||
|
||||
continue;
|
||||
} else if (info_idx == 6) {
|
||||
size_t wis[3] = { 0 };
|
||||
err = clGetDeviceInfo(ocl_device, ocl_dev_info, sizeof(size_t) * 3, wis, 0);
|
||||
if (err != CL_SUCCESS) {
|
||||
printf("Error: clGetDeviceInfo(work_items_size) failed (%d)\n", err);
|
||||
free (ocl_devices);
|
||||
free (*cd_ctx);
|
||||
free (ocl_platforms);
|
||||
return -10;
|
||||
}
|
||||
|
||||
if (verbose) printf("%14s: (%zu,%zu,%zu)\n", "Max Work-Items", wis[0], wis[1], wis[2]);
|
||||
|
||||
#if APPLE_GPU_BROKEN == 1
|
||||
if (wis[1] < GLOBAL_WS_1 && (*cd_ctx)[platform_idx].device[device_idx].is_apple_gpu) {
|
||||
(*cd_ctx)[platform_idx].device[device_idx].unsupported = true;
|
||||
}
|
||||
#endif
|
||||
continue;
|
||||
} else if (info_idx == 7) {
|
||||
cl_uint cores = 0;
|
||||
err = clGetDeviceInfo(ocl_device, ocl_dev_info, sizeof(cl_uint), &cores, 0);
|
||||
if (err != CL_SUCCESS) {
|
||||
printf("Error: clGetDeviceInfo(compute_units) failed (%d)\n", err);
|
||||
free (ocl_devices);
|
||||
free (*cd_ctx);
|
||||
free (ocl_platforms);
|
||||
return -10;
|
||||
}
|
||||
|
||||
if (verbose) printf("%14s: %u\n", "Compute Units", cores);
|
||||
|
||||
(*cd_ctx)[platform_idx].device[device_idx].compute_units = cores;
|
||||
continue;
|
||||
}
|
||||
|
||||
tmp_len = 0;
|
||||
tmp_buf = NULL;
|
||||
|
||||
err = clGetDeviceInfo(ocl_device, ocl_dev_info, 0, NULL, &tmp_len);
|
||||
if (err != CL_SUCCESS) {
|
||||
printf("Error: clGetDeviceInfo(param size) failed (%d)\n", err);
|
||||
free (ocl_devices);
|
||||
free (*cd_ctx);
|
||||
free (ocl_platforms);
|
||||
return -10;
|
||||
}
|
||||
|
||||
if (tmp_len > 0) {
|
||||
if (!(tmp_buf = (char *) calloc(tmp_len, sizeof(char)))) {
|
||||
printf("Error: calloc (ocl_dev_info %u) failed (%d): %s\n", info_idx, errno, strerror(errno));
|
||||
free (ocl_devices);
|
||||
free (*cd_ctx);
|
||||
free (ocl_platforms);
|
||||
return -7;
|
||||
}
|
||||
|
||||
err = clGetDeviceInfo(ocl_device, ocl_dev_info, tmp_len, tmp_buf, 0);
|
||||
if (err != CL_SUCCESS) {
|
||||
printf("Error: clGetDeviceInfo(param) failed (%d)\n", err);
|
||||
free (tmp_buf);
|
||||
free (ocl_devices);
|
||||
free (*cd_ctx);
|
||||
free (ocl_platforms);
|
||||
return -10;
|
||||
}
|
||||
} else {
|
||||
tmp_len = 4;
|
||||
if (!(tmp_buf = (char *) calloc(tmp_len, sizeof(char)))) {
|
||||
printf("Error: calloc (ocl_dev_info %u) failed (%d): %s\n", info_idx, errno, strerror(errno));
|
||||
free (ocl_devices);
|
||||
free (*cd_ctx);
|
||||
free (ocl_platforms);
|
||||
return -7;
|
||||
}
|
||||
|
||||
strncpy(tmp_buf, "N/A\0", tmp_len);
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
const char *tmp_dev_info_desc = (info_idx == 1) ? "Name" : (info_idx == 2) ? "Version" : (info_idx == 3) ? "Driver Version" : "Vendor";
|
||||
|
||||
printf("%14s: %s\n", tmp_dev_info_desc, tmp_buf);
|
||||
}
|
||||
|
||||
switch (info_idx) {
|
||||
case 1:
|
||||
strncpy((*cd_ctx)[platform_idx].device[device_idx].name, tmp_buf, tmp_len < 0xff ? tmp_len : 0xff - 1);
|
||||
break;
|
||||
case 2:
|
||||
strncpy((*cd_ctx)[platform_idx].device[device_idx].version, tmp_buf, tmp_len < 0x40 ? tmp_len : 0x40 - 1);
|
||||
break;
|
||||
case 3:
|
||||
strncpy((*cd_ctx)[platform_idx].device[device_idx].driver_version, tmp_buf, tmp_len < 0x40 ? tmp_len : 0x40 - 1);
|
||||
break;
|
||||
case 4:
|
||||
strncpy((*cd_ctx)[platform_idx].device[device_idx].vendor, tmp_buf, tmp_len < 0x40 ? tmp_len : 0x40 - 1);
|
||||
break;
|
||||
}
|
||||
|
||||
if (info_idx == 1) {
|
||||
// force profile to 0-1 with Jetson Nano
|
||||
if (strstr(tmp_buf, "Tegra") && (*cd_ctx)[platform_idx].is_pocl) {
|
||||
(*cd_ctx)[platform_idx].device[device_idx].profile = (profile_selected > 1) ? 0 : profile_selected;
|
||||
}
|
||||
} else if (info_idx == 4) {
|
||||
if (!strncmp(tmp_buf, "Intel", 5)) {
|
||||
if ((*cd_ctx)[platform_idx].is_apple) {
|
||||
(*cd_ctx)[platform_idx].device[device_idx].is_apple_gpu = (*cd_ctx)[platform_idx].device[device_idx].is_gpu;
|
||||
}
|
||||
|
||||
// force profile to 0 with Intel GPU and 2 wih Intel CPU's
|
||||
if ((*cd_ctx)[platform_idx].is_intel) {
|
||||
if ((*cd_ctx)[platform_idx].device[device_idx].is_gpu) {
|
||||
(*cd_ctx)[platform_idx].device[device_idx].profile = 0; // Intel GPU's, work better with a very slow profile
|
||||
} else {
|
||||
(*cd_ctx)[platform_idx].device[device_idx].profile = (profile_selected > 2) ? PROFILE_DEFAULT : profile_selected; // Intel CPU's
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!strncmp(tmp_buf, "NVIDIA", 6) && (*cd_ctx)[platform_idx].is_nv) {
|
||||
unsigned int sm_maj = 0, sm_min = 0;
|
||||
|
||||
err = clGetDeviceInfo(ocl_device, 0x4000, sizeof(unsigned int), &sm_maj, 0);
|
||||
err |= clGetDeviceInfo(ocl_device, 0x4001, sizeof(unsigned int), &sm_min, 0);
|
||||
|
||||
if (err != CL_SUCCESS) {
|
||||
printf("Error: clGetDeviceInfo(sm_maj/sm_min) failed (%d)\n", err);
|
||||
free (tmp_buf);
|
||||
free (ocl_devices);
|
||||
free (*cd_ctx);
|
||||
free (ocl_platforms);
|
||||
return -10;
|
||||
}
|
||||
|
||||
(*cd_ctx)[platform_idx].device[device_idx].sm_maj = sm_maj;
|
||||
(*cd_ctx)[platform_idx].device[device_idx].sm_min = sm_min;
|
||||
|
||||
if (verbose) printf("%14s: %u%u\n", "SM", sm_maj, sm_min);
|
||||
|
||||
if (sm_maj >= 5) { // >= Maxwell
|
||||
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#logic-and-shift-instructions-lop3
|
||||
// Requires sm_50 or higher.
|
||||
(*cd_ctx)[platform_idx].device[device_idx].have_lop3 = true;
|
||||
} else {
|
||||
(*cd_ctx)[platform_idx].device[device_idx].warning = true;
|
||||
}
|
||||
|
||||
(*cd_ctx)[platform_idx].device[device_idx].is_nv = true;
|
||||
|
||||
if ((*cd_ctx)[platform_idx].device[device_idx].is_gpu) {
|
||||
if (profile_selected > 10) {
|
||||
// NVIDIA RTX 3090 perform better with 5
|
||||
(*cd_ctx)[platform_idx].device[device_idx].profile = (sm_maj >= 8) ? 5 : PROFILE_DEFAULT;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
(*cd_ctx)[platform_idx].device[device_idx].warning = true;
|
||||
}
|
||||
}
|
||||
|
||||
free (tmp_buf);
|
||||
}
|
||||
|
||||
if (!show && verbose) printf("%14s: %s\n", "Selected", ((*cd_ctx)[platform_idx].device[device_idx].selected) ? "yes" : "no");
|
||||
|
||||
if ((*cd_ctx)[platform_idx].device[device_idx].unsupported) {
|
||||
printf("\n%14s: this device was not supported, beacuse of missing resources\n\n", "=====> Warning");
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((*cd_ctx)[platform_idx].device[device_idx].warning) {
|
||||
if (!show && verbose) printf("\n%14s: performance will not be optimal using this device\n\n", "=====> Warning");
|
||||
}
|
||||
|
||||
(*cd_ctx)[platform_idx].device[device_idx].device_id = ocl_device;
|
||||
}
|
||||
free (ocl_devices);
|
||||
ocl_devices = NULL;
|
||||
}
|
||||
|
||||
free (ocl_platforms);
|
||||
ocl_platforms = NULL;
|
||||
|
||||
*platform_detected_cnt = ocl_platform_cnt;
|
||||
|
||||
if (show) free (*cd_ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int runKernel(opencl_ctx_t *ctx, uint32_t cand_base, uint64_t *matches, uint32_t *matches_found, size_t id) {
|
||||
int err = 0;
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ License: GNU General Public License v3 or any later version (see LICENSE.txt)
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
// max number of concurrent devices (tested up to 4x RTX 3090)
|
||||
#define MAX_OPENCL_DEVICES 16
|
||||
@@ -54,9 +55,10 @@ typedef struct compute_device_ctx {
|
||||
bool warning, unsupported;
|
||||
|
||||
bool selected;
|
||||
bool enabled;
|
||||
|
||||
unsigned char pad1[4];
|
||||
unsigned char pad1[1];
|
||||
unsigned int profile;
|
||||
|
||||
unsigned int sm_maj;
|
||||
unsigned int sm_min;
|
||||
unsigned int compute_units;
|
||||
@@ -70,11 +72,11 @@ typedef struct compute_platform_ctx {
|
||||
unsigned int device_cnt;
|
||||
unsigned int compute_units_max;
|
||||
|
||||
bool is_nv, is_apple, is_intel;
|
||||
bool is_nv, is_apple, is_intel, is_pocl;
|
||||
bool warning;
|
||||
bool selected;
|
||||
|
||||
unsigned char pad1[3];
|
||||
unsigned char pad1[2];
|
||||
compute_device_ctx_t device[0x10];
|
||||
|
||||
char name[0xff];
|
||||
@@ -94,7 +96,7 @@ typedef struct opencl_ctx {
|
||||
|
||||
size_t *global_ws;
|
||||
size_t *local_ws;
|
||||
int *profiles;
|
||||
unsigned int *profiles;
|
||||
|
||||
cl_device_id *device_ids; // compute device id's array
|
||||
cl_context *contexts; // compute contexts
|
||||
@@ -120,7 +122,8 @@ typedef struct opencl_ctx {
|
||||
} opencl_ctx_t;
|
||||
|
||||
bool plat_dev_enabled(unsigned int id, unsigned int *sel, unsigned int cnt, unsigned int cur_type, unsigned int allow_type);
|
||||
|
||||
unsigned int get_smallest_profile (compute_platform_ctx_t *cd_ctx, size_t ocl_platform_cnt);
|
||||
int discoverDevices(unsigned int profile_selected, uint32_t device_types_selected, cl_uint *ocl_platform_cnt, size_t *selected_platforms_cnt, size_t *selected_devices_cnt, compute_platform_ctx_t **cd_ctx, unsigned int *plat_sel, unsigned int plat_cnt, unsigned int *dev_sel, unsigned int dev_cnt, bool verbose, bool show);
|
||||
int runKernel(opencl_ctx_t *ctx, uint32_t cand_base, uint64_t *matches, uint32_t *matches_found, size_t id);
|
||||
|
||||
#endif // OPENCL_H
|
||||
|
||||
@@ -340,7 +340,7 @@ int wu_queue_pop(wu_queue_ctx_t *ctx, wu_queue_data_t *wu, short remove) {
|
||||
break;
|
||||
case QUEUE_TYPE_RANDOM: // from the head
|
||||
#if TEST_UNIT == 1
|
||||
fprintf(stdout, "pop id %ld\n", wu->id);
|
||||
fprintf(stdout, "pop id %zu\n", wu->id);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
if (ptrPrev == NULL) {
|
||||
@@ -441,9 +441,9 @@ int main(void) {
|
||||
|
||||
wu_queue_type_t types[4] = { QUEUE_TYPE_FORWARD, QUEUE_TYPE_REVERSE, QUEUE_TYPE_RANDOM, 1234 };
|
||||
int types_max = (int)(sizeof(types) / sizeof(wu_queue_type_t));
|
||||
int ret = 0;
|
||||
|
||||
for (i = 0; i < types_max; i++) {
|
||||
int ret = 0;
|
||||
printf("[%d] trying wu_queue_init() in %s mode\n", i, wu_queue_strdesc(types[i]));
|
||||
|
||||
if ((ret = wu_queue_init(&ctx, types[i])) != 0) {
|
||||
|
||||
@@ -95,7 +95,7 @@ typedef struct wu_queue_ctx {
|
||||
|
||||
// mutex
|
||||
pthread_mutexattr_t queue_mutex_attr;
|
||||
// unsigned char pad1[4];
|
||||
unsigned char pad1[4];
|
||||
pthread_mutex_t queue_mutex;
|
||||
|
||||
} wu_queue_ctx_t;
|
||||
|
||||
@@ -56,6 +56,8 @@ const char *thread_strerror(int error) {
|
||||
return (const char *) "GENERIC ERROR";
|
||||
case THREAD_ERROR_ALLOC:
|
||||
return (const char *) "ALLOC FAILED";
|
||||
case THREAD_ERROR_INTERNAL:
|
||||
return (const char *) "INTERNAL ERROR";
|
||||
}
|
||||
|
||||
return (const char *) "GENERIC";
|
||||
@@ -174,6 +176,198 @@ int thread_init(thread_ctx_t *ctx, short type, size_t thread_count) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int thread_start_scheduler (thread_ctx_t *ctx, thread_args_t *t_arg, wu_queue_ctx_t *queue_ctx)
|
||||
{
|
||||
size_t z = 0;
|
||||
bool found = false;
|
||||
bool done = false;
|
||||
unsigned int th_cnt = 0;
|
||||
|
||||
if (ctx->type == THREAD_TYPE_SEQ) {
|
||||
bool error = false;
|
||||
uint32_t slice = 0;
|
||||
for (slice = 0; slice < t_arg[0].max_slices; slice += ctx->thread_count) {
|
||||
int err = 0;
|
||||
|
||||
if ((err = thread_start(ctx, t_arg)) != 0) {
|
||||
printf("Error: thread_start() failed (%d): %s\n", err, thread_strerror(err));
|
||||
}
|
||||
|
||||
// waiting threads return
|
||||
if (err == 0) thread_stop(ctx);
|
||||
|
||||
for (z = 0; z < ctx->thread_count; z++) {
|
||||
if (t_arg[z].r) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (t_arg[z].err) {
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
|
||||
// internel err
|
||||
if (error && err == 0) {
|
||||
thread_destroy(ctx);
|
||||
err = THREAD_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
if (err != 0) return err;
|
||||
|
||||
if (found) break;
|
||||
}
|
||||
} else if (ctx->type == THREAD_TYPE_ASYNC) {
|
||||
|
||||
// crack hitag key or die tryin'
|
||||
do { // master
|
||||
th_cnt = 0;
|
||||
|
||||
for (z = 0; z < ctx->thread_count; z++) {
|
||||
#if TDEBUG >= 1 && DEBUGME == 1
|
||||
if (ctx->thread_count == 1) { printf("[%zu] get status from thread ...\n", z); fflush(stdout); }
|
||||
#endif
|
||||
|
||||
pthread_mutex_lock(&ctx->thread_mutexs[z]);
|
||||
thread_status_t cur_status = t_arg[z].status;
|
||||
pthread_mutex_unlock(&ctx->thread_mutexs[z]);
|
||||
|
||||
#if TDEBUG >= 1 && DEBUGME == 1
|
||||
if (ctx->thread_count == 1) { printf("[%zu] thread status: %s\n", z, thread_status_strdesc(cur_status)); fflush(stdout); }
|
||||
#endif
|
||||
if (found) {
|
||||
#if TDEBUG >= 3
|
||||
printf("[%zu] Processing exit logic\n", z);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
if (cur_status < TH_FOUND_KEY) {
|
||||
#if TDEBUG >= 1
|
||||
printf("[%zu] key found from another thread, set quit\n", z);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
pthread_mutex_lock(&ctx->thread_mutexs[z]);
|
||||
t_arg[z].status = TH_END;
|
||||
t_arg[z].quit = true;
|
||||
if (cur_status == TH_WAIT) pthread_cond_signal(&ctx->thread_conds[z]);
|
||||
pthread_mutex_unlock(&ctx->thread_mutexs[z]);
|
||||
} else {
|
||||
if (ctx->thread_count == 1) {
|
||||
th_cnt++;
|
||||
#if TDEBUG >= 1
|
||||
printf("[%zu] Increment th_cnt: %u/%zu\n", z, th_cnt, ctx->thread_count);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cur_status == TH_WAIT) {
|
||||
pthread_mutex_lock(&ctx->thread_mutexs[z]);
|
||||
|
||||
if (found) {
|
||||
#if TDEBUG >= 1
|
||||
printf("[%zu] key is found in another thread 1\n", z);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
t_arg[z].status = TH_END;
|
||||
t_arg[z].quit = true;
|
||||
pthread_mutex_unlock(&ctx->thread_mutexs[z]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (wu_queue_done(queue_ctx) != QUEUE_EMPTY) {
|
||||
t_arg[z].status = TH_PROCESSING;
|
||||
|
||||
#if TDEBUG >= 1
|
||||
printf("[master] thread [%zu], I give you another try (%s)\n", z, thread_status_strdesc(t_arg[z].status));
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
pthread_cond_signal(&ctx->thread_conds[z]);
|
||||
pthread_mutex_unlock(&ctx->thread_mutexs[z]);
|
||||
continue;
|
||||
} else {
|
||||
#if TDEBUG >= 1
|
||||
printf("[master] thread [%zu], max step reached. Quit.\n", z);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
cur_status = t_arg[z].status = TH_END;
|
||||
t_arg[z].quit = true;
|
||||
|
||||
pthread_cond_signal(&ctx->thread_conds[z]);
|
||||
pthread_mutex_unlock(&ctx->thread_mutexs[z]);
|
||||
}
|
||||
}
|
||||
|
||||
if (cur_status == TH_PROCESSING) {
|
||||
if (ctx->enable_condusleep) {
|
||||
#if TDEBUG >= 1
|
||||
printf("[master] before pthread_cond_wait, TH_PROCESSING\n");
|
||||
fflush(stdout);
|
||||
#endif
|
||||
pthread_mutex_lock(&ctx->thread_mutex_usleep);
|
||||
#if TDEBUG >= 1
|
||||
printf("[master] thread [%zu], I'm waiting you end of task, I'm in %s give me a signal.\n", z, thread_status_strdesc(t_arg[z].status));
|
||||
fflush(stdout);
|
||||
#endif
|
||||
pthread_cond_wait(&ctx->thread_cond_usleep, &ctx->thread_mutex_usleep);
|
||||
#if TDEBUG >= 1
|
||||
printf("[master] thread [%zu], got the signal with new state: %s.\n", z, thread_status_strdesc(t_arg[z].status));
|
||||
fflush(stdout);
|
||||
#endif
|
||||
if (t_arg[z].status == TH_FOUND_KEY) found = true;
|
||||
|
||||
pthread_mutex_unlock(&ctx->thread_mutex_usleep);
|
||||
#if TDEBUG >= 1
|
||||
printf("[master] after pthread_cond_wait, TH_PROCESSING\n");
|
||||
fflush(stdout);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
if (found) {
|
||||
#if TDEBUG >= 1
|
||||
printf("[master] thread [%zu], the key is found. set TH_END from TH_PROCESSING\n", z);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
pthread_mutex_lock(&ctx->thread_mutexs[z]);
|
||||
t_arg[z].status = TH_END;
|
||||
t_arg[z].quit = true;
|
||||
pthread_mutex_unlock(&ctx->thread_mutexs[z]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (cur_status == TH_ERROR) {
|
||||
// something went wrong
|
||||
pthread_mutex_lock(&ctx->thread_mutexs[z]);
|
||||
t_arg[z].status = TH_END;
|
||||
t_arg[z].quit = true;
|
||||
pthread_mutex_unlock(&ctx->thread_mutexs[z]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cur_status >= TH_FOUND_KEY) {
|
||||
th_cnt++;
|
||||
|
||||
if (cur_status == TH_FOUND_KEY) {
|
||||
thread_setEnd(ctx, t_arg);
|
||||
found = true;
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (th_cnt == ctx->thread_count) done = true;
|
||||
|
||||
} while (!done);
|
||||
}
|
||||
|
||||
return (found) ? 0 : 1;
|
||||
}
|
||||
|
||||
int thread_destroy(thread_ctx_t *ctx) {
|
||||
if (!ctx) return -1;
|
||||
if (!ctx->init) return -2;
|
||||
@@ -258,8 +452,6 @@ const char *thread_status_strdesc(thread_status_t s) {
|
||||
return (const char *) "PROCESSING";
|
||||
case TH_ERROR:
|
||||
return (const char *) "ERROR";
|
||||
case TH_STOP:
|
||||
return (const char *) "STOP";
|
||||
case TH_FOUND_KEY:
|
||||
return (const char *) "FOUND_KEY";
|
||||
case TH_END:
|
||||
@@ -274,11 +466,10 @@ bool thread_setEnd(thread_ctx_t *ctx, thread_args_t *t_arg) {
|
||||
|
||||
size_t z;
|
||||
|
||||
int m_ret = 0;
|
||||
int c_ret = 0;
|
||||
|
||||
for (z = 0; z < ctx->thread_count; z++) {
|
||||
m_ret = pthread_mutex_lock(&ctx->thread_mutexs[z]);
|
||||
int m_ret = pthread_mutex_lock(&ctx->thread_mutexs[z]);
|
||||
if (m_ret != 0) {
|
||||
tprintf("[%zu] [%s] Error: pthread_mutex_lock() failed (%d): %s\n", z, __func__, m_ret, strerror(m_ret));
|
||||
}
|
||||
@@ -296,10 +487,10 @@ bool thread_setEnd(thread_ctx_t *ctx, thread_args_t *t_arg) {
|
||||
}
|
||||
|
||||
#if DEBUGME > 0
|
||||
tprintf("[%zu] [%s] Set thread status to TH_STOP\n", z, __func__);
|
||||
tprintf("[%zu] [%s] Set thread status to TH_END\n", z, __func__);
|
||||
#endif
|
||||
|
||||
t_arg[z].status = TH_STOP;
|
||||
t_arg[z].status = TH_END;
|
||||
|
||||
if (tmp == TH_WAIT) {
|
||||
#if DEBUGME > 0
|
||||
@@ -366,7 +557,7 @@ void *computing_process(void *arg) {
|
||||
|
||||
if (!ctx->force_hitag2_opencl) {
|
||||
#if DEBUGME >= 2
|
||||
printf("[slave][%zu] master, I found %5u candidates @ slice %zu\n", z, matches_found[0], a->slice + 1);
|
||||
printf("[%s][%zu] master, I found %5u candidates @ slice %zu\n", __func__, z, matches_found[0], a->slice + 1);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
@@ -378,7 +569,7 @@ void *computing_process(void *arg) {
|
||||
// the OpenCL kernel return only one key if found, else nothing
|
||||
|
||||
#if TDEBUG >= 1
|
||||
printf("[slave][%zu] master, I found the key @ slice %zu\n", z, a->slice + 1);
|
||||
printf("[%s][%zu] master, I found the key @ slice %zu\n", __func__, z, a->slice + 1);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
@@ -400,32 +591,31 @@ void *computing_process_async(void *arg) {
|
||||
// fetching data from thread struct, I hope they are good
|
||||
thread_status_t status = a->status;
|
||||
|
||||
uint64_t *matches = a->matches;
|
||||
uint32_t *matches_found = a->matches_found;
|
||||
uint32_t uid = a->uid;
|
||||
uint32_t aR2 = a->aR2;
|
||||
uint32_t nR1 = a->nR1;
|
||||
uint32_t nR2 = a->nR2;
|
||||
|
||||
uint64_t *matches = a->matches;
|
||||
uint32_t *matches_found = a->matches_found;
|
||||
size_t max_step = a->max_step;
|
||||
size_t max_slices = a->max_slices;
|
||||
|
||||
opencl_ctx_t *ctx = a->ocl_ctx;
|
||||
|
||||
pthread_mutex_unlock(&a->thread_ctx->thread_mutexs[z]);
|
||||
|
||||
uint64_t off = 0;
|
||||
// size_t slice = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (status == TH_START) {
|
||||
#if TDEBUG >= 1
|
||||
printf("[slave][%zu] plat id %d, uid %u, aR2 %u, nR1 %u, nR2 %u, Initial status: %s\n", z, ctx->id_platform, uid, aR2, nR1, nR2, thread_status_strdesc(status));
|
||||
printf("[%s][%zu] plat id %d, uid %u, aR2 %u, nR1 %u, nR2 %u, Initial status: %s\n", __func__, z, ctx->id_platform, uid, aR2, nR1, nR2, thread_status_strdesc(status));
|
||||
#endif
|
||||
status = TH_WAIT;
|
||||
// proceed to next
|
||||
}
|
||||
|
||||
do { // slave
|
||||
do {
|
||||
if (status == TH_WAIT) {
|
||||
pthread_mutex_lock(&a->thread_ctx->thread_mutexs[z]);
|
||||
|
||||
@@ -433,7 +623,7 @@ void *computing_process_async(void *arg) {
|
||||
|
||||
if (a->status == TH_END) { // other threads found the key
|
||||
fflush(stdout);
|
||||
status = TH_END;
|
||||
//status = TH_END;
|
||||
a->quit = true;
|
||||
pthread_mutex_unlock(&a->thread_ctx->thread_mutexs[z]);
|
||||
pthread_exit(NULL);
|
||||
@@ -444,7 +634,7 @@ void *computing_process_async(void *arg) {
|
||||
pthread_mutex_lock(&a->thread_ctx->thread_mutex_usleep);
|
||||
pthread_cond_signal(&a->thread_ctx->thread_cond_usleep); // unlock master/TH_PROCESSING cond
|
||||
#if TDEBUG >= 1
|
||||
printf("[slate][%zu] after pthread_cond_signal TH_WAIT\n", z);
|
||||
printf("[%s][%zu] after pthread_cond_signal TH_WAIT\n", __func__, z);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
pthread_mutex_unlock(&a->thread_ctx->thread_mutex_usleep);
|
||||
@@ -452,7 +642,7 @@ void *computing_process_async(void *arg) {
|
||||
}
|
||||
|
||||
#if TDEBUG >= 1
|
||||
printf("[slave][%zu] master, i'm here to serve you. I'm in %s give me a signal.\n", z, thread_status_strdesc(status));
|
||||
printf("[%s][%zu] master, i'm here to serve you. I'm in %s give me a signal.\n", __func__, z, thread_status_strdesc(status));
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
@@ -461,7 +651,7 @@ void *computing_process_async(void *arg) {
|
||||
status = a->status; // read new status from master
|
||||
|
||||
#if TDEBUG >= 2
|
||||
printf("[slave][%zu] master, got the signal with new state: %s.\n", z, thread_status_strdesc(status));
|
||||
printf("[%s][%zu] master, got the signal with new state: %s.\n", __func__, z, thread_status_strdesc(status));
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
@@ -469,7 +659,7 @@ void *computing_process_async(void *arg) {
|
||||
|
||||
if (status == TH_WAIT) {
|
||||
#if TDEBUG >=1
|
||||
printf("[slave] ! Error: need to be TH_PROCESSING or TH_END, not TH_WAIT ... exit\n");
|
||||
printf("[%s] ! Error: need to be TH_PROCESSING or TH_END, not TH_WAIT ... exit\n", __func__);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
break;
|
||||
@@ -478,7 +668,7 @@ void *computing_process_async(void *arg) {
|
||||
|
||||
if (status == TH_ERROR) {
|
||||
#if TDEBUG >= 1
|
||||
printf("[slave][%zu] master, got error signal, proceed with exit\n", z);
|
||||
printf("[%s][%zu] master, got error signal, proceed with exit\n", __func__, z);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
pthread_exit(NULL);
|
||||
@@ -486,7 +676,7 @@ void *computing_process_async(void *arg) {
|
||||
|
||||
if (status == TH_PROCESSING) {
|
||||
#if TDEBUG >= 2
|
||||
printf("[slave][%zu] master, got a work-unit, processing ...\n", z);
|
||||
printf("[%s][%zu] master, got a work-unit, processing ...\n", __func__, z);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
@@ -521,7 +711,7 @@ void *computing_process_async(void *arg) {
|
||||
a->status = TH_ERROR;
|
||||
pthread_mutex_unlock(&a->thread_ctx->thread_mutexs[z]);
|
||||
#if TDEBUG >= 1
|
||||
printf("[slave][%zu] master, something is broken, exit\n", z);
|
||||
printf("[%s][%zu] master, something is broken, exit\n", __func__, z);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
@@ -529,7 +719,7 @@ void *computing_process_async(void *arg) {
|
||||
pthread_mutex_lock(&a->thread_ctx->thread_mutex_usleep);
|
||||
pthread_cond_signal(&a->thread_ctx->thread_cond_usleep); // unlock master/TH_PROCESSING cond
|
||||
#if TDEBUG >= 1
|
||||
printf("[slave][%zu] after pthread_cond_signal TH_ERROR\n", z);
|
||||
printf("[%s][%zu] after pthread_cond_signal TH_ERROR\n", __func__, z);
|
||||
#endif
|
||||
pthread_mutex_unlock(&a->thread_ctx->thread_mutex_usleep);
|
||||
}
|
||||
@@ -539,12 +729,12 @@ void *computing_process_async(void *arg) {
|
||||
}
|
||||
|
||||
#if TDEBUG >= 1
|
||||
printf("[slave][%zu] master, process is done but no candidates found\n", z);
|
||||
printf("[%s][%zu] master, process is done but no candidates found\n", __func__, z);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
pthread_mutex_lock(&a->thread_ctx->thread_mutexs[z]);
|
||||
|
||||
if (a->slice >= max_step) a->status = TH_END;
|
||||
if (a->slice >= max_slices) a->status = TH_END;
|
||||
else a->status = TH_WAIT;
|
||||
|
||||
status = a->status;
|
||||
@@ -555,7 +745,7 @@ void *computing_process_async(void *arg) {
|
||||
pthread_mutex_lock(&a->thread_ctx->thread_mutex_usleep);
|
||||
pthread_cond_signal(&a->thread_ctx->thread_cond_usleep); // unlock master/TH_PROCESSING cond
|
||||
#if TDEBUG >= 1
|
||||
printf("[slave][%zu] after pthread_cond_signal TH_WAIT\n", z);
|
||||
printf("[%s][%zu] after pthread_cond_signal TH_WAIT\n", __func__, z);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
pthread_mutex_unlock(&a->thread_ctx->thread_mutex_usleep);
|
||||
@@ -566,7 +756,7 @@ void *computing_process_async(void *arg) {
|
||||
|
||||
if (!ctx->force_hitag2_opencl) {
|
||||
#if TDEBUG >= 1
|
||||
printf("[slave][%zu] master, we got %5u candidates. Proceed to validation\n", z, matches_found[0]);
|
||||
printf("[%s][%zu] master, we got %5u candidates. Proceed to validation\n", __func__, z, matches_found[0]);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
@@ -576,7 +766,7 @@ void *computing_process_async(void *arg) {
|
||||
a->status = TH_END;
|
||||
pthread_mutex_unlock(&a->thread_ctx->thread_mutexs[z]);
|
||||
#if TDEBUG >= 1
|
||||
printf("[slave][%zu] master, Another thread found the key, quit 2 \n", z);
|
||||
printf("[%s][%zu] master, Another thread found the key, quit 2 \n", __func__, z);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
@@ -584,7 +774,8 @@ void *computing_process_async(void *arg) {
|
||||
pthread_mutex_lock(&a->thread_ctx->thread_mutex_usleep);
|
||||
pthread_cond_signal(&a->thread_ctx->thread_cond_usleep); // unlock master/TH_PROCESSING cond
|
||||
#if TDEBUG >= 1
|
||||
printf("[slave][%zu] after pthread_cond_signal TH_END\n", z);
|
||||
printf("[%s][%zu] after pthread_cond_signal TH_END\n", __func__, z);
|
||||
fflush (stdout);
|
||||
#endif
|
||||
pthread_mutex_unlock(&a->thread_ctx->thread_mutex_usleep);
|
||||
}
|
||||
@@ -600,7 +791,7 @@ void *computing_process_async(void *arg) {
|
||||
a->quit = true;
|
||||
pthread_mutex_unlock(&a->thread_ctx->thread_mutexs[z]);
|
||||
#if TDEBUG >= 1
|
||||
printf("[slave][%zu] master, I found the key ! state %" STR(OFF_FORMAT_U) ", slice %zu\n", z, a->s, a->slice + 1);
|
||||
printf("[%s][%zu] master, I found the key ! state %" STR(OFF_FORMAT_U) ", slice %zu\n", __func__, z, a->s, a->slice + 1);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
@@ -608,7 +799,7 @@ void *computing_process_async(void *arg) {
|
||||
pthread_mutex_lock(&a->thread_ctx->thread_mutex_usleep);
|
||||
pthread_cond_signal(&a->thread_ctx->thread_cond_usleep); // unlock master/TH_PROCESSING cond
|
||||
#if TDEBUG >= 1
|
||||
printf("[slave][%zu] after pthread_cond_signal TH_FOUND_KEY\n", z);
|
||||
printf("[%s][%zu] after pthread_cond_signal TH_FOUND_KEY\n", __func__, z);
|
||||
#endif
|
||||
pthread_mutex_unlock(&a->thread_ctx->thread_mutex_usleep);
|
||||
}
|
||||
@@ -622,7 +813,7 @@ void *computing_process_async(void *arg) {
|
||||
a->status = TH_END;
|
||||
pthread_mutex_unlock(&a->thread_ctx->thread_mutexs[z]);
|
||||
#if TDEBUG >= 1
|
||||
printf("[slave][%zu] master, Another thread found the key, quit 1 \n", z);
|
||||
printf("[%s][%zu] master, Another thread found the key, quit 1 \n", __func__, z);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
@@ -630,7 +821,7 @@ void *computing_process_async(void *arg) {
|
||||
pthread_mutex_lock(&a->thread_ctx->thread_mutex_usleep);
|
||||
pthread_cond_signal(&a->thread_ctx->thread_cond_usleep); // unlock master/TH_PROCESSING cond
|
||||
#if TDEBUG >= 1
|
||||
printf("[slave][%zu] after pthread_cond_signal TH_END\n", z);
|
||||
printf("[%s][%zu] after pthread_cond_signal TH_END\n", __func__, z);
|
||||
#endif
|
||||
pthread_mutex_unlock(&a->thread_ctx->thread_mutex_usleep);
|
||||
}
|
||||
@@ -651,7 +842,7 @@ void *computing_process_async(void *arg) {
|
||||
a->quit = true;
|
||||
pthread_mutex_unlock(&a->thread_ctx->thread_mutexs[z]);
|
||||
#if TDEBUG >= 1
|
||||
printf("[slave][%zu] master, I found the key at slice %zu\n", z, a->slice + 1);
|
||||
printf("[%s][%zu] master, I found the key at slice %zu\n", __func__, z, a->slice + 1);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
@@ -659,7 +850,7 @@ void *computing_process_async(void *arg) {
|
||||
pthread_mutex_lock(&a->thread_ctx->thread_mutex_usleep);
|
||||
pthread_cond_signal(&a->thread_ctx->thread_cond_usleep); // unlock master/TH_PROCESSING cond
|
||||
#if TDEBUG >= 1
|
||||
printf("[slave][%zu] after pthread_cond_signal TH_FOUND_KEY\n", z);
|
||||
printf("[%s][%zu] after pthread_cond_signal TH_FOUND_KEY\n", __func__, z);
|
||||
#endif
|
||||
pthread_mutex_unlock(&a->thread_ctx->thread_mutex_usleep);
|
||||
}
|
||||
@@ -671,10 +862,10 @@ void *computing_process_async(void *arg) {
|
||||
if (status >= TH_FOUND_KEY) {
|
||||
#if TDEBUG >= 1
|
||||
if (status == TH_FOUND_KEY) {
|
||||
printf("[slave][%zu] master, TH_FOUND_KEY, if you see this message, something is wrong\n", z);
|
||||
printf("[%s][%zu] master, TH_FOUND_KEY, if you see this message, something is wrong\n", __func__, z);
|
||||
fflush(stdout);
|
||||
} else if (status == TH_END) {
|
||||
printf("[slave][%zu] master, TH_END reached\n", z);
|
||||
printf("[%s][%zu] master, TH_END reached\n", __func__, z);
|
||||
fflush(stdout);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -38,7 +38,6 @@ typedef enum thread_status {
|
||||
TH_START = 0,
|
||||
TH_WAIT,
|
||||
TH_PROCESSING,
|
||||
TH_STOP,
|
||||
TH_ERROR,
|
||||
TH_FOUND_KEY,
|
||||
TH_END
|
||||
@@ -66,7 +65,8 @@ typedef enum thread_error {
|
||||
THREAD_ERROR_MUTEX_USLEEP = -11,
|
||||
THREAD_ERROR_COND_USLEEP = -12,
|
||||
THREAD_ERROR_GENERIC = -13,
|
||||
THREAD_ERROR_ALLOC = -14
|
||||
THREAD_ERROR_ALLOC = -14,
|
||||
THREAD_ERROR_INTERNAL = -15
|
||||
|
||||
} thread_error_t;
|
||||
|
||||
@@ -92,6 +92,7 @@ typedef struct threads_ctx {
|
||||
pthread_attr_t attr;
|
||||
pthread_mutexattr_t mutex_attr;
|
||||
|
||||
unsigned char pad3[4];
|
||||
} thread_ctx_t;
|
||||
|
||||
// used by threads engine
|
||||
@@ -105,13 +106,13 @@ typedef struct thread_arg {
|
||||
bool r;
|
||||
bool err;
|
||||
bool quit;
|
||||
bool async;
|
||||
|
||||
unsigned char pad2[1];
|
||||
uint64_t off;
|
||||
uint64_t *matches;
|
||||
uint32_t *matches_found;
|
||||
size_t slice;
|
||||
size_t max_step;
|
||||
size_t max_slices;
|
||||
size_t device_id;
|
||||
|
||||
uint64_t key;
|
||||
@@ -124,11 +125,12 @@ typedef struct thread_arg {
|
||||
int thread_init(thread_ctx_t *ctx, short type, size_t thread_count);
|
||||
int thread_start(thread_ctx_t *ctx, thread_args_t *args);
|
||||
int thread_stop(thread_ctx_t *ctx);
|
||||
int thread_start_scheduler(thread_ctx_t *ctx, thread_args_t *t_arg, wu_queue_ctx_t *queue_ctx);
|
||||
bool thread_setEnd(thread_ctx_t *ctx, thread_args_t *t_arg);
|
||||
|
||||
void tprintf(const char *restrict format, ...);
|
||||
const char *thread_strerror(int error);
|
||||
const char *thread_status_strdesc(thread_status_t s);
|
||||
bool thread_setEnd(thread_ctx_t *ctx, thread_args_t *t_arg);
|
||||
|
||||
void *computing_process(void *arg);
|
||||
void *computing_process_async(void *arg);
|
||||
|
||||
Reference in New Issue
Block a user