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,
524 for(i = 0; i <
sizeof(XCODERS_RETRY_LCK_NAME) /
sizeof(XCODERS_RETRY_LCK_NAME[0]); ++i)
526 retry_shm_fd = open(XCODERS_RETRY_LCK_NAME[i], O_RDWR | O_CREAT | O_CLOEXEC | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
531 ni_log(
NI_LOG_ERROR,
"Failed to create %s ERROR: %s\n", XCODERS_RETRY_LCK_NAME[i], strerror(errno));
577 char shm_name[32] = { 0 };
578 char lck_name[32] = { 0 };
581 HANDLE map_file_handle = NULL;
582 ni_lock_handle_t mutex_handle = NULL;
583 SECURITY_DESCRIPTOR security_descriptor = { 0 };
592 ni_log(
NI_LOG_DEBUG,
"%s(): shm_name %s, lck_name %s\n", __func__, shm_name, lck_name);
595 mutex_handle = CreateMutex(NULL,
598 if (NULL == mutex_handle)
604 if (WAIT_ABANDONED == WaitForSingleObject(mutex_handle, INFINITE))
607 "obtain mutex: %p\n", mutex_handle);
611 InitializeSecurityDescriptor(&security_descriptor, SECURITY_DESCRIPTOR_REVISION);
614 map_file_handle = CreateFileMapping(
615 INVALID_HANDLE_VALUE,
623 if (NULL == map_file_handle)
633 if (ERROR_ALREADY_EXISTS == rc)
640 ni_log(
NI_LOG_INFO,
"CreateFileMapping created a new mapFile for %s, handle: %p ..\n", shm_name, map_file_handle);
652 if (NULL == p_coder_info_map)
662 if (p_coder_info_map)
664 UnmapViewOfFile(p_coder_info_map);
668 ReleaseMutex(mutex_handle);
688 if ((!p_device_context) || (!p_session_context))
738 const int existing_number_of_devices,
743 HANDLE map_file_handle = NULL;
745 map_file_handle = CreateFileMapping(
746 INVALID_HANDLE_VALUE,
754 if (NULL == map_file_handle)
763 if(ERROR_ALREADY_EXISTS == rc)
765 ni_log(
NI_LOG_INFO,
"NETINT resources have been initialized already, exiting ..\n");
766 CloseHandle(map_file_handle);
771 ni_log(
NI_LOG_INFO,
"NETINT resources not initialized, starting initialization ..\n");
783 if (NULL == p_device_queue)
787 CloseHandle(map_file_handle);
796 UnmapViewOfFile(p_device_queue);
797 CloseHandle(map_file_handle);
801 if (WAIT_ABANDONED == WaitForSingleObject(lock, INFINITE))
806 UnmapViewOfFile(p_device_queue);
807 CloseHandle(map_file_handle);
811 fill_shared_memory(p_device_queue,
813 existing_number_of_devices,
814 existing_device_names);
816 UnmapViewOfFile(p_device_queue);
821 #elif __linux__ || __APPLE__
826 static bool check_correctness_count(
const ni_device_queue_t *existing_device_queue,
827 const int should_match_rev,
828 const int existing_number_of_devices,
831 uint32_t max_io_size;
835 ni_device_handle_t device_handle;
841 for (i = 0; i < existing_number_of_devices; i++)
844 if (device_handle == NI_INVALID_DEVICE_HANDLE)
852 (should_match_rev && \
862 if (existing_device_queue->
xcoders[j][i] == -1 && device_capability.
xcoder_cnt[j] != 0)
867 if (existing_device_queue->
xcoders[k][i] != -1)
870 "ERROR: %s(): Discovered device %s is not in queue for module %s but is in %s\n",
893 "WARNING: %s(): Discovered %u %s, expected %u\n",
905 const int existing_number_of_devices,
913 for (i = 0; i < existing_number_of_devices; i++)
917 module_id = existing_device_queue->
xcoders[j][i];
927 "WARNING: %s(): Missing device context for %s %s\n",
946 static void sigbus_handler(
int signal)
951 static void setup_signal_handler(
struct sigaction *p,
const int signum)
955 memset(&c, 0,
sizeof(
struct sigaction));
956 if (sigemptyset(&c.sa_mask) == -1)
959 "ERROR: %s(): Could not initialize signal set: %d\n",
964 c.sa_handler = sigbus_handler;
966 if (sigaction(signum, NULL, p) == -1)
969 "ERROR: %s(): Could not save previous signal handler: %d\n",
975 if (sigaction(signum, &c, NULL) == -1)
978 "ERROR: %s(): Could not register signal handler: %d\n",
987 const int should_match_rev,
988 const int existing_number_of_devices,
993 const int signum = SIGBUS;
996 setup_signal_handler(&p, signum);
998 if (sigsetjmp(env, 1))
1004 if (!check_correctness_count(existing_device_queue,
1006 existing_number_of_devices,
1012 if (!check_device_queue(existing_device_queue,
1013 existing_number_of_devices,
1024 if (sigaction(signum, &p, NULL) == -1)
1027 "ERROR: %s(): Could not restore previous signal handler: %d\n",
1037 const int existing_number_of_devices,
1041 int return_value = 0;
1044 ni_rsrc_shm_state state = NI_RSRC_SHM_IS_INVALID;
1045 int flags = O_CREAT | O_RDWR | O_CLOEXEC;
1046 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
1049 if ((ni_rsrc_try_get_shm_lock(
CODERS_LCK_NAME, flags, mode, &lck_fd) < 0) ||
1058 (
void **)&p_device_queue)) < 0) {
1065 if (NI_RSRC_SHM_IS_EXISTED == state) {
1066 if (check_correctness(p_device_queue,
1068 existing_number_of_devices,
1069 existing_device_names))
1077 if (lockf(lck_fd, F_ULOCK, 0) < 0) {
1083 #ifndef __OPENHARMONY__
1086 ni_rsrc_remove_all_shm();
1088 if (limit_depth <= 0)
1093 existing_number_of_devices,
1094 existing_device_names,
1098 fill_shared_memory(p_device_queue,
1100 existing_number_of_devices,
1101 existing_device_names);
1104 if (p_device_queue && p_device_queue != MAP_FAILED) {
1106 p_device_queue = NULL;
1111 if (lockf(lck_fd, F_ULOCK, 0) < 0) {
1118 #ifndef __OPENHARMONY__
1124 return return_value;
1136 int32_t shm_fd = -1;
1137 ni_rsrc_shm_state state = NI_RSRC_SHM_IS_INVALID;
1139 int flags = O_CREAT | O_RDWR | O_CLOEXEC;
1140 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
1141 char shm_name[32] = { 0 };
1142 char lck_name[32] = { 0 };
1145 if(! p_device_info) {
1152 ni_log(
NI_LOG_DEBUG,
"%s(): shm_name %s, lck_name %s\n", __func__, shm_name, lck_name);
1154 if (ni_rsrc_try_get_shm_lock(lck_name, flags, mode, (
int *)&lock) < 0) {
1159 if (ni_rsrc_open_shm(shm_name,
1162 (
int *)&shm_fd) < 0) {
1167 if ((ni_rsrc_mmap_shm(shm_name,
1170 (
void **)&p_coder_info_dst)) < 0) {
1177 #ifndef __OPENHARMONY__
1178 if (msync((
void*)p_coder_info_dst,
sizeof(
ni_device_info_t), MS_SYNC | MS_INVALIDATE)) {
1187 if (p_coder_info_dst && p_coder_info_dst != MAP_FAILED) {
1189 p_coder_info_dst = NULL;
1193 #ifndef __OPENHARMONY__
1199 if (lockf(lock, F_ULOCK, 0) < 0) {
1200 ni_log(
NI_LOG_ERROR,
"Will exit from %s(), but failed to unlock lck_fd for %s\n", __func__, shm_name);
1219 if ((!p_device_context) || (!p_session_context))
1252 "p_device_info: %s\n", __func__, strerror(
NI_ERRNO));
1271 char *domain,
char *slot,
char *dev,
char *func)
1279 char path[PATH_MAX];
1282 if(!device_name || !strstr(device_name,
"/dev/nvme") || !pcie)
1288 char *start = device_name + 5;
1291 snprintf(path,
sizeof(path),
"/sys/block/%s", start);
1295 char target[PATH_MAX];
1297 ssize_t len = readlink(path, target,
sizeof(target) - 1);
1306 char *saveptr = NULL;
1308 pcie[4] = pcie[7] =
':';
1311 while(ptr != NULL) {
1313 if (strlen(ptr) == 12)
1315 ret = sscanf(ptr,
"%4c:%2c:%2c.%1c", pcie, pcie+5,pcie+8,pcie+11);
1318 ni_log2(NULL,
NI_LOG_DEBUG,
"\tsscanf error %d errno %d %s\n", ret, errno, strerror(errno));
1326 if (!domain || !slot || !dev || !func)
1330 domain[4] = slot[2] = dev[2] = func[1] =
'\0';
1331 sscanf(pcie,
"%4[^:]:%2[^:]:%2[^.].%1s", domain, slot, dev, func);
1332 ni_log2(NULL,
NI_LOG_DEBUG,
"\t%d: Domain: %s, Slot: %s, Device: %s, Function: %s\n", i, domain, slot, dev, func);
1352 ni_retcode_t ni_rsrc_try_get_shm_lock(
const char *lck_name,
1359 if (!lck_name || !lck_fd) {
1366 if (0 != mkdir(
LOCK_DIR, S_IRWXU | S_IRWXG | S_IRWXO)) {
1373 lock = open(lck_name, flags, mode);
1376 __func__, lck_name, strerror(
NI_ERRNO));
1382 while (lockf(lock, F_TLOCK, 0) != 0)
1386 if (retry_cnt >= 900)
1389 ni_log(
NI_LOG_ERROR,
"ERROR %s() If persists, stop traffic and run rm /dev/shm/NI_*\n", __func__);
1400 #if defined(__OPENHARMONY__)
1401 static ni_retcode_t openharmony_open_shm(
const char *shm_name,
1403 ni_rsrc_shm_state *state,
1407 int flag = IPC_CREAT | IPC_EXCL;
1408 char shm_path[PATH_MAX];
1410 if (!shm_name || !shm_fd) {
1415 memset(shm_path, 0, PATH_MAX);
1416 snprintf(shm_path, PATH_MAX,
"%s/%s",
LOCK_DIR, shm_name);
1419 if (0 != access(shm_path, F_OK)) {
1420 int fd = open(shm_path, O_RDWR | O_CREAT | O_CLOEXEC,
1421 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
1431 key_t key = ftok(shm_path, PROJ_ID);
1437 *state = NI_RSRC_SHM_IS_CREATED;
1440 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
1441 shm_id = shmget(key, shm_size, mode | flag);
1444 *state = NI_RSRC_SHM_IS_EXISTED;
1446 shm_id = shmget(key, shm_size, mode | flag);
1459 static ni_retcode_t openharmony_remove_shm(
const char *shm_name,
1463 char shm_path[PATH_MAX];
1470 memset(shm_path, 0, PATH_MAX);
1471 snprintf(shm_path, PATH_MAX,
"%s/%s",
LOCK_DIR, shm_name);
1474 if (0 != access(shm_path, F_OK)) {
1479 key_t key = ftok(shm_path, PROJ_ID);
1486 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
1487 shm_id = shmget(key, shm_size, mode);
1493 shmctl(shm_id, IPC_RMID,
nullptr);
1498 #elif defined(_ANDROID)
1499 static ni_retcode_t android_open_shm(
const char *shm_name,
1501 ni_rsrc_shm_state *state,
1504 int shm_fd_tmp = -1;
1506 if (!shm_name || !shm_fd) {
1517 *state = NI_RSRC_SHM_IS_CREATED;
1519 string param = shm_name;
1520 Return<void> retvalue =
1521 service->GetAppFlag(param, [&](int32_t ret, hidl_handle handle) {
1523 *state = NI_RSRC_SHM_IS_EXISTED;
1524 shm_fd_tmp = dup(handle->data[0]);
1530 if (!retvalue.isOk()) {
1535 if (shm_fd_tmp < 0) {
1536 int fd = ashmem_create_region(shm_name, shm_size);
1538 native_handle_t *native_handle = native_handle_create(1, 0);
1539 if (!native_handle) {
1543 native_handle->data[0] = fd;
1546 handle.setTo(native_handle,
true);
1547 service->SetAppFlag(param, handle);
1548 shm_fd_tmp = dup(fd);
1554 *shm_fd = shm_fd_tmp;
1559 static ni_retcode_t android_remove_shm(
const char *shm_name,
1573 string param = shm_name;
1574 Return<void> retvalue =
service->RemoveAppFlag(param);
1575 if (!retvalue.isOk()) {
1591 Return<void> retvalue =
service->RemoveAllAppFlags();
1592 if (!retvalue.isOk()) {
1601 static ni_retcode_t linux_open_shm(
const char *shm_name,
1603 ni_rsrc_shm_state *state,
1606 int shm_fd_tmp = -1;
1607 const mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
1608 int flag = O_CREAT | O_EXCL | O_RDWR;
1609 bool skip_ftruncate =
false;
1611 if (!shm_name || !shm_fd) {
1616 *state = NI_RSRC_SHM_IS_CREATED;
1619 shm_fd_tmp = shm_open(shm_name, flag, mode);
1620 if (shm_fd_tmp < 0) {
1622 skip_ftruncate =
true;
1623 *state = NI_RSRC_SHM_IS_EXISTED;
1625 shm_fd_tmp = shm_open(shm_name, flag, mode);
1628 if (shm_fd_tmp < 0) {
1630 __func__, shm_name, strerror(
NI_ERRNO));
1636 if (!skip_ftruncate && ftruncate(shm_fd_tmp, shm_size) < 0) {
1638 shm_unlink(shm_name);
1642 *shm_fd = shm_fd_tmp;
1668 ni_rsrc_shm_state *state,
1671 #if defined(__OPENHARMONY__)
1672 return openharmony_open_shm(shm_name, shm_size, state, shm_fd);
1673 #elif defined(_ANDROID)
1674 return android_open_shm(shm_name, shm_size, state, shm_fd);
1676 return linux_open_shm(shm_name, shm_size, state, shm_fd);
1699 if (!shm_name || !shm_addr) {
1704 #ifdef __OPENHARMONY__
1705 *shm_addr = shmat(shm_fd,
nullptr, 0);
1706 if ((
void *)(-1) == *shm_addr) {
1712 *shm_addr = mmap(0, shm_size, PROT_READ | PROT_WRITE,
1713 MAP_SHARED, shm_fd, 0);
1714 if (MAP_FAILED == *shm_addr) {
1743 #ifdef __OPENHARMONY__
1746 munmap(shm_addr, shm_size);
1767 #ifdef __OPENHARMONY__
1768 return openharmony_remove_shm(shm_name, shm_size);
1769 #elif defined(_ANDROID)
1770 return android_remove_shm(shm_name, shm_size);
1772 shm_unlink(shm_name);
1791 struct dirent *dirent;
1792 char path_to_remove[PATH_MAX];
1803 while ((dirent = readdir(dir)) != NULL) {
1804 if (strncmp(dirent->d_name,
"NI_", 3) != 0) {
1808 snprintf(path_to_remove, PATH_MAX,
"%s/%s",
LOCK_DIR, dirent->d_name);
1811 if (strncasecmp(dirent->d_name,
"NI_SHM", 6) == 0) {
1812 #ifdef __OPENHARMONY__
1813 openharmony_remove_shm(dirent->d_name, 1);
1815 shm_unlink(dirent->d_name);
1820 remove(path_to_remove);
1824 android_remove_all_shm();
1827 if (closedir(dir) == -1) {