topo_utils.cpp 2.74 KB
Newer Older
lishen's avatar
lishen committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <string.h>
#include "topo_utils.h"

namespace sccl {
namespace hardware {
namespace topology {

scclResult_t int64ToBusId(int64_t id, char* busId) {
    sprintf(busId, "%04lx:%02lx:%02lx.%01lx", (id) >> 20, (id & 0xff000) >> 12, (id & 0xff0) >> 4, (id & 0xf));
    return scclSuccess;
}

scclResult_t busIdToInt64(const char* busId, int64_t* id) {
    char hexStr[17]; // Longest possible int64 hex string + null terminator.
    int hexOffset = 0;
    for(int i = 0; hexOffset < sizeof(hexStr) - 1; i++) {
        char c = busId[i];
        if(c == '.' || c == ':')
            continue;
        if((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f')) {
            hexStr[hexOffset++] = busId[i];
        } else
            break;
    }
    hexStr[hexOffset] = '\0';
    *id               = strtol(hexStr, NULL, 16);
    return scclSuccess;
}

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// 定义一个常量,表示最大字符串长度
static constexpr int MAX_STR_LEN = 255;

/**
 * @brief 从系统文件中读取字符串内容
 *
 * 该函数通过拼接路径和文件名,打开指定文件并读取其内容到字符串缓冲区中。
 * 如果读取失败或文件为空,会将缓冲区置为空字符串并记录警告信息。
 *
 * @param path 文件所在目录路径
 * @param fileName 要读取的文件名
 * @param strValue 用于存储读取内容的字符串缓冲区
 * @return scclResult_t 始终返回scclSuccess
 *
 * @note 缓冲区最大长度为MAX_STR_LEN,超出部分会被截断
 *       文件内容末尾会自动添加字符串结束符'\0'
 */
scclResult_t scclTopoGetStrFromSys(const char* path, const char* fileName, char* strValue) {
    char filePath[PATH_MAX];
    sprintf(filePath, "%s/%s", path, fileName);
    int offset = 0;
    FILE* file;
    if((file = fopen(filePath, "r")) != NULL) {
        while(feof(file) == 0 && ferror(file) == 0 && offset < MAX_STR_LEN) {
            int len = fread(strValue + offset, 1, MAX_STR_LEN - offset, file);
            offset += len;
        }
        fclose(file);
    }

    if(offset == 0) {
        strValue[0] = '\0';
        INFO(SCCL_LOG_TOPO, "System detection : could not read %s, ignoring", filePath);
    } else {
        strValue[offset - 1] = '\0';
    }
    return scclSuccess;
}

lishen's avatar
lishen committed
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
scclResult_t pciPathToInt64(char* path, int offset, int minOffset, int64_t* id) {
    char* str = path + offset;
    // Remove trailing "/"
    if(*str == '/')
        str--;
    // Find next /
    while(*str != '/')
        str--;
    str++;
    int64_t numid;
    SCCLCHECK(busIdToInt64(str, &numid));
    // Ignore subdevice because those should use the same PCI link so we want to merge nodes.
    numid -= numid & 0xf;
    *id = numid;
    return scclSuccess;
}

} // namespace topology
} // namespace hardware
} // namespace sccl