38 #if __linux__ || __APPLE__
39 #ifdef __OPENHARMONY__
45 #include <sys/types.h>
53 #include <sys/syslimits.h>
67 #if __linux__ || __APPLE__
207 const char *l = (
const char *)p_str;
208 const char *r = (
const char *)p_str1;
211 while (!isdigit(*l) && (*l) !=
'\0')
215 while (!isdigit(*r) && (*r) !=
'\0')
249 snprintf(p_name, max_name_len,
"%s/NI_QUADRA_lck_%c%d",
LOCK_DIR, type, guid);
253 snprintf(p_name, max_name_len,
"%s/NI_lck_%c%d",
LOCK_DIR, type, guid);
273 snprintf(p_name, max_name_len,
"NI_QUADRA_shm_%c%d", type, guid);
277 snprintf(p_name, max_name_len,
"NI_shm_%c%d", type, guid);
284 const ni_device_handle_t device_handle,
286 const int fw_ver_compat_warning,
300 memcpy(device_info->
fw_rev,
301 device_capability->
fw_rev,
302 sizeof(device_info->
fw_rev));
338 const int should_match_rev,
339 const int existing_number_of_devices,
342 int i, j, compatible_device_counter;
349 device_queue->
xcoders[i][j] = -1;
353 compatible_device_counter = 0;
354 for (i = 0; i < existing_number_of_devices; i++)
363 compatible_device_counter++;
367 "Maximum number of supported and compatible devices "
368 "reached. Ignoring other supported and compatible "
382 uint32_t guid_mask[4] = {0};
386 temp_guid = device_queue->
xcoders[device_type][i];
389 guid_mask[temp_guid / 32] |= (1u << ((uint32_t)temp_guid % 32));
393 for (i = 0; i < 4; i++)
395 for (j = 0; j < 32; j++)
397 if ((guid_mask[i] & (1u << j)) == 0)
399 *guidn = (i * 32) + j;
409 const bool device_open_should_succeed,
410 const int should_match_rev,
414 int i, j, fw_compat_cmp;
415 uint32_t max_io_size;
416 char fw_api_ver_str[5];
419 ni_device_handle_t device_handle;
425 if (device_handle == NI_INVALID_DEVICE_HANDLE)
427 if (device_open_should_succeed)
430 "ERROR: %s(): Failed to add %s\n: Failed ni_device_open()\n",
451 if (should_match_rev && \
456 "Skipping %s init: device FW v%s incompatible with this version of Libxcoder\n",
469 "%s %s disabled...\n",
476 guid = j ? device_queue->
xcoders[i][j-1] + 1 : 0;
480 "initialized devices exceeds %d\n", __FUNCTION__,
485 device_queue->
xcoders[i][j] = guid;
488 fill_device_info(&device_info,
492 (should_match_rev && fw_compat_cmp) ? 1 : 0,
499 if (fw_compat_cmp < 0) {
501 "Libxcoder supported FW API version\n", device_name,
503 }
else if (fw_compat_cmp > 0) {
505 "Libxcoder supported FW API version\n", device_name,
543 char shm_name[32] = { 0 };
544 char lck_name[32] = { 0 };
547 HANDLE map_file_handle = NULL;
548 ni_lock_handle_t mutex_handle = NULL;
549 SECURITY_DESCRIPTOR security_descriptor = { 0 };
558 ni_log(
NI_LOG_DEBUG,
"%s(): shm_name %s, lck_name %s\n", __func__, shm_name, lck_name);
561 mutex_handle = CreateMutex(NULL,
564 if (NULL == mutex_handle)
570 if (WAIT_ABANDONED == WaitForSingleObject(mutex_handle, INFINITE))
573 "obtain mutex: %p\n", mutex_handle);
577 InitializeSecurityDescriptor(&security_descriptor, SECURITY_DESCRIPTOR_REVISION);
580 map_file_handle = CreateFileMapping(
581 INVALID_HANDLE_VALUE,
589 if (NULL == map_file_handle)
599 if (ERROR_ALREADY_EXISTS == rc)
606 ni_log(
NI_LOG_INFO,
"CreateFileMapping created a new mapFile for %s, handle: %p ..\n", shm_name, map_file_handle);
618 if (NULL == p_coder_info_map)
628 if (p_coder_info_map)
630 UnmapViewOfFile(p_coder_info_map);
634 ReleaseMutex(mutex_handle);
654 if ((!p_device_context) || (!p_session_context))
704 const int existing_number_of_devices,
709 HANDLE map_file_handle = NULL;
711 map_file_handle = CreateFileMapping(
712 INVALID_HANDLE_VALUE,
720 if (NULL == map_file_handle)
729 if(ERROR_ALREADY_EXISTS == rc)
731 ni_log(
NI_LOG_INFO,
"NETINT resources have been initialized already, exiting ..\n");
732 CloseHandle(map_file_handle);
737 ni_log(
NI_LOG_INFO,
"NETINT resources not initialized, starting initialization ..\n");
749 if (NULL == p_device_queue)
753 CloseHandle(map_file_handle);
762 UnmapViewOfFile(p_device_queue);
763 CloseHandle(map_file_handle);
767 if (WAIT_ABANDONED == WaitForSingleObject(lock, INFINITE))
772 UnmapViewOfFile(p_device_queue);
773 CloseHandle(map_file_handle);
777 fill_shared_memory(p_device_queue,
779 existing_number_of_devices,
780 existing_device_names);
782 UnmapViewOfFile(p_device_queue);
787 #elif __linux__ || __APPLE__
792 static bool check_correctness_count(
const ni_device_queue_t *existing_device_queue,
793 const int should_match_rev,
794 const int existing_number_of_devices,
797 uint32_t max_io_size;
801 ni_device_handle_t device_handle;
807 for (i = 0; i < existing_number_of_devices; i++)
810 if (device_handle == NI_INVALID_DEVICE_HANDLE)
818 (should_match_rev && \
828 if (existing_device_queue->
xcoders[j][i] == -1 && device_capability.
xcoder_cnt[j] != 0)
833 if (existing_device_queue->
xcoders[k][i] != -1)
836 "ERROR: %s(): Discovered device %s is not in queue for module %s but is in %s\n",
859 "WARNING: %s(): Discovered %u %s, expected %u\n",
871 const int existing_number_of_devices,
879 for (i = 0; i < existing_number_of_devices; i++)
883 module_id = existing_device_queue->
xcoders[j][i];
893 "WARNING: %s(): Missing device context for %s %s\n",
912 static void sigbus_handler(
int signal)
917 static void setup_signal_handler(
struct sigaction *p,
const int signum)
921 memset(&c, 0,
sizeof(
struct sigaction));
922 if (sigemptyset(&c.sa_mask) == -1)
925 "ERROR: %s(): Could not initialize signal set: %d\n",
930 c.sa_handler = sigbus_handler;
932 if (sigaction(signum, NULL, p) == -1)
935 "ERROR: %s(): Could not save previous signal handler: %d\n",
941 if (sigaction(signum, &c, NULL) == -1)
944 "ERROR: %s(): Could not register signal handler: %d\n",
953 const int should_match_rev,
954 const int existing_number_of_devices,
959 const int signum = SIGBUS;
962 setup_signal_handler(&p, signum);
964 if (sigsetjmp(env, 1))
970 if (!check_correctness_count(existing_device_queue,
972 existing_number_of_devices,
978 if (!check_device_queue(existing_device_queue,
979 existing_number_of_devices,
990 if (sigaction(signum, &p, NULL) == -1)
993 "ERROR: %s(): Could not restore previous signal handler: %d\n",
1003 const int existing_number_of_devices,
1007 int return_value = 0;
1010 ni_rsrc_shm_state state = NI_RSRC_SHM_IS_INVALID;
1011 int flags = O_CREAT | O_RDWR | O_CLOEXEC;
1012 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
1015 if ((ni_rsrc_try_get_shm_lock(
CODERS_LCK_NAME, flags, mode, &lck_fd) < 0) ||
1024 (
void **)&p_device_queue)) < 0) {
1031 if (NI_RSRC_SHM_IS_EXISTED == state) {
1032 if (check_correctness(p_device_queue,
1034 existing_number_of_devices,
1035 existing_device_names))
1043 if (lockf(lck_fd, F_ULOCK, 0) < 0) {
1049 #ifndef __OPENHARMONY__
1052 ni_rsrc_remove_all_shm();
1054 if (limit_depth <= 0)
1059 existing_number_of_devices,
1060 existing_device_names,
1064 fill_shared_memory(p_device_queue,
1066 existing_number_of_devices,
1067 existing_device_names);
1070 if (p_device_queue && p_device_queue != MAP_FAILED) {
1072 p_device_queue = NULL;
1077 if (lockf(lck_fd, F_ULOCK, 0) < 0) {
1084 #ifndef __OPENHARMONY__
1090 return return_value;
1102 int32_t shm_fd = -1;
1103 ni_rsrc_shm_state state = NI_RSRC_SHM_IS_INVALID;
1105 int flags = O_CREAT | O_RDWR | O_CLOEXEC;
1106 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
1107 char shm_name[32] = { 0 };
1108 char lck_name[32] = { 0 };
1111 if(! p_device_info) {
1118 ni_log(
NI_LOG_DEBUG,
"%s(): shm_name %s, lck_name %s\n", __func__, shm_name, lck_name);
1120 if (ni_rsrc_try_get_shm_lock(lck_name, flags, mode, (
int *)&lock) < 0) {
1125 if (ni_rsrc_open_shm(shm_name,
1128 (
int *)&shm_fd) < 0) {
1133 if ((ni_rsrc_mmap_shm(shm_name,
1136 (
void **)&p_coder_info_dst)) < 0) {
1143 #ifndef __OPENHARMONY__
1144 if (msync((
void*)p_coder_info_dst,
sizeof(
ni_device_info_t), MS_SYNC | MS_INVALIDATE)) {
1153 if (p_coder_info_dst && p_coder_info_dst != MAP_FAILED) {
1155 p_coder_info_dst = NULL;
1159 #ifndef __OPENHARMONY__
1165 if (lockf(lock, F_ULOCK, 0) < 0) {
1166 ni_log(
NI_LOG_ERROR,
"Will exit from %s(), but failed to unlock lck_fd for %s\n", __func__, shm_name);
1185 if ((!p_device_context) || (!p_session_context))
1218 "p_device_info: %s\n", __func__, strerror(
NI_ERRNO));
1237 char *domain,
char *slot,
char *dev,
char *func)
1245 char path[PATH_MAX];
1248 if(!device_name || !strstr(device_name,
"/dev/nvme") || !pcie)
1254 char *start = device_name + 5;
1257 snprintf(path,
sizeof(path),
"/sys/block/%s", start);
1261 char target[PATH_MAX];
1263 ssize_t len = readlink(path, target,
sizeof(target) - 1);
1272 char *saveptr = NULL;
1274 pcie[4] = pcie[7] =
':';
1277 while(ptr != NULL) {
1279 if (strlen(ptr) == 12)
1281 ret = sscanf(ptr,
"%4c:%2c:%2c.%1c", pcie, pcie+5,pcie+8,pcie+11);
1284 ni_log2(NULL,
NI_LOG_DEBUG,
"\tsscanf error %d errno %d %s\n", ret, errno, strerror(errno));
1292 if (!domain || !slot || !dev || !func)
1296 domain[4] = slot[2] = dev[2] = func[1] =
'\0';
1297 sscanf(pcie,
"%4[^:]:%2[^:]:%2[^.].%1s", domain, slot, dev, func);
1298 ni_log2(NULL,
NI_LOG_DEBUG,
"\t%d: Domain: %s, Slot: %s, Device: %s, Function: %s\n", i, domain, slot, dev, func);
1318 ni_retcode_t ni_rsrc_try_get_shm_lock(
const char *lck_name,
1325 if (!lck_name || !lck_fd) {
1332 if (0 != mkdir(
LOCK_DIR, S_IRWXU | S_IRWXG | S_IRWXO)) {
1339 lock = open(lck_name, flags, mode);
1342 __func__, lck_name, strerror(
NI_ERRNO));
1348 while (lockf(lock, F_TLOCK, 0) != 0)
1352 if (retry_cnt >= 900)
1355 ni_log(
NI_LOG_ERROR,
"ERROR %s() If persists, stop traffic and run rm /dev/shm/NI_*\n", __func__);
1366 #if defined(__OPENHARMONY__)
1367 static ni_retcode_t openharmony_open_shm(
const char *shm_name,
1369 ni_rsrc_shm_state *state,
1373 int flag = IPC_CREAT | IPC_EXCL;
1374 char shm_path[PATH_MAX];
1376 if (!shm_name || !shm_fd) {
1381 memset(shm_path, 0, PATH_MAX);
1382 snprintf(shm_path, PATH_MAX,
"%s/%s",
LOCK_DIR, shm_name);
1385 if (0 != access(shm_path, F_OK)) {
1386 int fd = open(shm_path, O_RDWR | O_CREAT | O_CLOEXEC,
1387 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
1397 key_t key = ftok(shm_path, PROJ_ID);
1403 *state = NI_RSRC_SHM_IS_CREATED;
1406 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
1407 shm_id = shmget(key, shm_size, mode | flag);
1410 *state = NI_RSRC_SHM_IS_EXISTED;
1412 shm_id = shmget(key, shm_size, mode | flag);
1425 static ni_retcode_t openharmony_remove_shm(
const char *shm_name,
1429 char shm_path[PATH_MAX];
1436 memset(shm_path, 0, PATH_MAX);
1437 snprintf(shm_path, PATH_MAX,
"%s/%s",
LOCK_DIR, shm_name);
1440 if (0 != access(shm_path, F_OK)) {
1445 key_t key = ftok(shm_path, PROJ_ID);
1452 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
1453 shm_id = shmget(key, shm_size, mode);
1459 shmctl(shm_id, IPC_RMID,
nullptr);
1464 #elif defined(_ANDROID)
1465 static ni_retcode_t android_open_shm(
const char *shm_name,
1467 ni_rsrc_shm_state *state,
1470 int shm_fd_tmp = -1;
1472 if (!shm_name || !shm_fd) {
1483 *state = NI_RSRC_SHM_IS_CREATED;
1485 string param = shm_name;
1486 Return<void> retvalue =
1487 service->GetAppFlag(param, [&](int32_t ret, hidl_handle handle) {
1489 *state = NI_RSRC_SHM_IS_EXISTED;
1490 shm_fd_tmp = dup(handle->data[0]);
1496 if (!retvalue.isOk()) {
1501 if (shm_fd_tmp < 0) {
1502 int fd = ashmem_create_region(shm_name, shm_size);
1504 native_handle_t *native_handle = native_handle_create(1, 0);
1505 if (!native_handle) {
1509 native_handle->data[0] = fd;
1512 handle.setTo(native_handle,
true);
1513 service->SetAppFlag(param, handle);
1514 shm_fd_tmp = dup(fd);
1520 *shm_fd = shm_fd_tmp;
1525 static ni_retcode_t android_remove_shm(
const char *shm_name,
1539 string param = shm_name;
1540 Return<void> retvalue =
service->RemoveAppFlag(param);
1541 if (!retvalue.isOk()) {
1557 Return<void> retvalue =
service->RemoveAllAppFlags();
1558 if (!retvalue.isOk()) {
1567 static ni_retcode_t linux_open_shm(
const char *shm_name,
1569 ni_rsrc_shm_state *state,
1572 int shm_fd_tmp = -1;
1573 const mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
1574 int flag = O_CREAT | O_EXCL | O_RDWR;
1575 bool skip_ftruncate =
false;
1577 if (!shm_name || !shm_fd) {
1582 *state = NI_RSRC_SHM_IS_CREATED;
1585 shm_fd_tmp = shm_open(shm_name, flag, mode);
1586 if (shm_fd_tmp < 0) {
1588 skip_ftruncate =
true;
1589 *state = NI_RSRC_SHM_IS_EXISTED;
1591 shm_fd_tmp = shm_open(shm_name, flag, mode);
1594 if (shm_fd_tmp < 0) {
1596 __func__, shm_name, strerror(
NI_ERRNO));
1602 if (!skip_ftruncate && ftruncate(shm_fd_tmp, shm_size) < 0) {
1604 shm_unlink(shm_name);
1608 *shm_fd = shm_fd_tmp;
1634 ni_rsrc_shm_state *state,
1637 #if defined(__OPENHARMONY__)
1638 return openharmony_open_shm(shm_name, shm_size, state, shm_fd);
1639 #elif defined(_ANDROID)
1640 return android_open_shm(shm_name, shm_size, state, shm_fd);
1642 return linux_open_shm(shm_name, shm_size, state, shm_fd);
1665 if (!shm_name || !shm_addr) {
1670 #ifdef __OPENHARMONY__
1671 *shm_addr = shmat(shm_fd,
nullptr, 0);
1672 if ((
void *)(-1) == *shm_addr) {
1678 *shm_addr = mmap(0, shm_size, PROT_READ | PROT_WRITE,
1679 MAP_SHARED, shm_fd, 0);
1680 if (MAP_FAILED == *shm_addr) {
1709 #ifdef __OPENHARMONY__
1712 munmap(shm_addr, shm_size);
1733 #ifdef __OPENHARMONY__
1734 return openharmony_remove_shm(shm_name, shm_size);
1735 #elif defined(_ANDROID)
1736 return android_remove_shm(shm_name, shm_size);
1738 shm_unlink(shm_name);
1757 struct dirent *dirent;
1758 char path_to_remove[PATH_MAX];
1769 while ((dirent = readdir(dir)) != NULL) {
1770 if (strncmp(dirent->d_name,
"NI_", 3) != 0) {
1774 snprintf(path_to_remove, PATH_MAX,
"%s/%s",
LOCK_DIR, dirent->d_name);
1777 if (strncasecmp(dirent->d_name,
"NI_SHM", 6) == 0) {
1778 #ifdef __OPENHARMONY__
1779 openharmony_remove_shm(dirent->d_name, 1);
1781 shm_unlink(dirent->d_name);
1786 remove(path_to_remove);
1790 android_remove_all_shm();
1793 if (closedir(dir) == -1) {