/** * @param[out] J9OSMutex* The mutex to init * @return 1 on success, 0 otherwise */ intptr_t j9OSMutex_allocAndInit(J9OSMutex *mutex) { omrthread_library_t lib = GLOBAL_DATA(default_library); intptr_t rc = 1; *mutex = (J9OSMutex)omrthread_allocate_memory(lib, sizeof(**mutex), OMRMEM_CATEGORY_OSMUTEXES); rc = (NULL != *mutex) && (pthread_mutex_init(*mutex, NULL) == 0); return rc; }
/** * @param[in] J9OSCond* The cond to init * @return 1 on success and 0 otherwise */ intptr_t j9OSCond_allocAndInit(J9OSCond *cond) { omrthread_library_t lib = GLOBAL_DATA(default_library); intptr_t rc = 1; *cond = (J9OSCond)omrthread_allocate_memory(lib, sizeof(**cond), OMRMEM_CATEGORY_OSCONDVARS); #if J9THREAD_USE_MONOTONIC_COND_CLOCK rc = (NULL != *cond) && (pthread_cond_init(*cond, defaultCondAttr) == 0); #else rc = (NULL != *cond) && (pthread_cond_init(*cond, NULL) == 0); #endif return rc; }
/** * Malloc memory. * Helper function used by the library's pools. * * @param[in] user user data (thread library pointer) * @param[in] size size of struct to be alloc'd * @param[in] callsite ignored * @param[in] memoryCategory * @param[in] type ignored * @param[out] doInit ignored * @return pointer to the malloc'd memory * @retval NULL on failure * */ void * omrthread_mallocWrapper(void *user, uint32_t size, const char *callSite, uint32_t memoryCategory, uint32_t type, uint32_t *doInit) { return omrthread_allocate_memory((omrthread_library_t)user, size, memoryCategory); }
static intptr_t initializeNumaNodeData(omrthread_library_t threadLibrary, uintptr_t numNodes) { uintptr_t result = 0; numaNodeData = omrthread_allocate_memory(threadLibrary, sizeof(numaNodeData[0]) * (numNodes + 1), OMRMEM_CATEGORY_THREADS); if (NULL == numaNodeData) { result = -1; } else { DIR *nodes = NULL; unsigned long nodeIndex = 0; const char NODE_PATH[] = "/sys/devices/system/node/"; for (nodeIndex = 0; nodeIndex <= numNodes; nodeIndex++) { CPU_ZERO(&numaNodeData[nodeIndex].cpu_set); numaNodeData[nodeIndex].cpu_count = 0; } nodes = opendir(NODE_PATH); if (NULL == nodes) { result = -1; } else { struct dirent *node = readdir(nodes); if (NULL != node) { const char CPUMAP[] = "/cpumap"; char pathBuffer[sizeof(NODE_PATH) + sizeof(CPUMAP) + 16]; /* extra space for "node<n>" & terminating null */ strcpy(pathBuffer, NODE_PATH); char *nodeRoot = pathBuffer + sizeof(NODE_PATH) - 1; /* shortcut to the end of the string */ do { if (1 == sscanf(node->d_name, "node%lu", &nodeIndex)) { if (nodeIndex < numNodes) { strcpy(nodeRoot, node->d_name); strcat(nodeRoot, CPUMAP); int cpumapFile = open(pathBuffer, O_RDONLY); BOOLEAN cpumapOkay = FALSE; if (-1 != cpumapFile) { char defaultMapBuffer[128]; char * mapBuffer = defaultMapBuffer; size_t bufferSize = sizeof(defaultMapBuffer); size_t bytesRead = read(cpumapFile, mapBuffer, bufferSize); if (bytesRead == bufferSize) { /* buffer possibly not big enough */ bufferSize = 4096; mapBuffer = malloc(bufferSize); if (NULL == mapBuffer) { result = -1; close(cpumapFile); break; } size_t bytesRead = read(cpumapFile, mapBuffer, bufferSize-1); mapBuffer[bytesRead] = '\0'; } if ((0 != bytesRead) && (bytesRead < bufferSize-1)) { /* the buffer was too small */ /* scan from the end of the line (lowest numbered CPU) toward the front */ char *cursor = mapBuffer+strlen(mapBuffer); uint32_t charCount = 0; do { while ((cursor > mapBuffer) && !isxdigit(*cursor)) { /* find the start of the hex string */ cursor -= 1; } uint32_t cpuIndex = 4 * charCount; /* each hex digit represents 4 CPUs. Use the count from the last iteration */ while ((cursor > mapBuffer) && isxdigit(*cursor)) { charCount += 1; cursor -= 1; } uintmax_t cpuMap = strtoumax((cursor == mapBuffer)? cursor: cursor + 1, NULL, 16); /* cursor points to a non-hex char if not at the front of the buffer */ while ((0 != cpuMap)) { if (0 != (cpuMap & 1)) { CPU_SET(cpuIndex, &numaNodeData[nodeIndex + 1].cpu_set); numaNodeData[nodeIndex + 1].cpu_count += 1; /* add all cpus to the synthetic 0 node */ CPU_SET(cpuIndex, &numaNodeData[0].cpu_set); numaNodeData[0].cpu_count += 1; } cpuMap >>= 1; cpuIndex += 1; } } while (cursor > mapBuffer); } if (mapBuffer != defaultMapBuffer) { free(mapBuffer); } close(cpumapFile); cpumapOkay = TRUE; } if (!cpumapOkay) { /* read the directory entries */ strcpy(nodeRoot, node->d_name); /* strip off "/cpulist". Updates pathBuffer */ DIR *cpus = opendir(pathBuffer); if (NULL != cpus) { struct dirent *cpu = readdir(cpus); while (NULL != cpu) { unsigned long cpuIndex = 0; if (1 == sscanf(cpu->d_name, "cpu%lu", &cpuIndex)) { CPU_SET(cpuIndex, &numaNodeData[nodeIndex + 1].cpu_set); numaNodeData[nodeIndex + 1].cpu_count += 1; /* add all cpus to the synthetic 0 node */ CPU_SET(cpuIndex, &numaNodeData[0].cpu_set); numaNodeData[0].cpu_count += 1; } cpu = readdir(cpus); } closedir(cpus); } } } } node = readdir(nodes); } while (NULL != node); }