开发者
我要评分
获取效率
正确性
完整性
易理解
在线提单
论坛求助

API参考

函数说明

kpglibc库已优化函数如表 1 kpglibc库已优化函数列表所示。

表 1 kpglibc库已优化函数列表

名称 说明
strcpy 将源字符串复制到目标字符串,包括结尾的空字符(\0) 。
strcmp 比较两个字符串的内容,返回它们的字典顺序差异(小于、等于或大于零)。
memchr 在内存块中查找首次出现的指定字符,返回指向该字符的指针。
memcmp 比较两块内存区域的内容,返回它们的差异。
memcpy 将一块内存区域的内容复制到另一块内存区域,不允许源和目标区域重叠。
memmove 将一块内存区域的内容复制到另一块内存区域,允许源和目标区域重叠。
memset 将一块内存区域的所有字节设置为指定的值。
gettimeofday 获取当前系统时间,以秒和微秒表示。
clock_gettime 获取当前系统时间,以秒和纳秒表示。

仅支持鲲鹏平台下使用。函数接口遵从Glibc原函数的入参校验逻辑,接口内部不做完整入参校验,入参合法性及合理性由调用方业务来保证。

函数定义

strcpy

函数功能

将源字符串复制到目标字符串,包括结尾的空字符(\0)。复制过程中不会检查目标缓冲区的大小,因此如果目标缓冲区不足以容纳源字符串,将会导致缓冲区溢出。

函数定义

char *strcpy(char *dest, const char *src);

参数说明

参数名 描述 取值范围 输入/输出
dest 目标内存地址指针,接收源字符串的内容。 非空指针,指向的内存空间必须可写且足够大(能容纳src所有字符+\0) 输入/输出
src 指向要复制的数据源内存指针。 非空指针,指向源字符串地址,必须以\0结尾(否则行为未定义,可能导致崩溃或溢出) 输入

返回值

  • 成功:返回目标字符串的起始地址。
  • 失败:遵循开源Glibc,不返回特殊异常值。

必须确保目标字符串有足够的空间来容纳源字符串(包括结尾的\0),否则会引起内存溢出。

示例

#include <stdio.h>
#include <string.h>

int main() {
    char src[] = "Hello, World!";
    char dest[50];

    strcpy(dest, src);
    printf("Source: %s\n", src);
    printf("Destination: %s\n", dest);
    return 0;
}

运行结果:

Source: Hello, World!
Destination: Hello, World!

strcmp

函数功能

比较两个字符串的字典顺序。它逐个字符比较两个字符串,直到发现不同的字符或者到达字符串结束符(\0)。返回结果依据比较结果,返回正负值或0。

函数定义

int strcmp(const char *str1, const char *str2);

参数说明

参数名 描述 取值范围 输入/输出
str1 第一个字符串的指针。 非空指针,指向以\0结尾的字符串指针 输入
str2 第二个字符串的指针。 非空指针,指向以\0结尾的字符串指针 输入

返回值

  • 成功:返回值为整数。

    • 如果str1小于str2,返回负值。
    • 如果str1等于str2,返回0。
    • 如果str1大于str2,返回正值。
  • 失败:遵循开源Glibc,不返回特殊异常值。

比较区分字符的大小写,因此字符串“abc”和“ABC”是不同的。

示例

#include <stdio.h>
#include <string.h>

int main() {
    const char *str1 = "apple";
    const char *str2 = "banana";
    const char *str3 = "apple";
    const char *str4 = "Banana";
    const char *str5 = "APPLE";
    int result1 = strcmp(str1, str2);
    printf("apple compared to banana: %d\n", result1);
    int result2 = strcmp(str1, str3);
    printf("apple compared to apple: %d\n", result2);
    int result3 = strcmp(str1, str4);
    printf("apple compared to Banana: %d\n", result3);
    int result4 = strcmp(str5, str1);
    printf("APPLE compared to apple: %d\n", result4);

    return 0;
}

运行结果:

apple compared to banana: -60
apple compared to apple: 0
apple compared to Banana: 124
APPLE compared to apple: -128

memchr

函数功能

在给定的内存块中查找首次出现的指定字符。该函数返回指向内存中找到字符的指针,若未找到则返回NULL。

函数定义

void *memchr(const void *ptr, int value, size_t num);

参数说明

参数名 描述 取值范围 输入/输出
ptr 指向内存区域的指针,搜索将在此内存区域进行。 非空指针,指向有效内存,至少有num字节可访问。 输入
value 要查找的字符,传入的值会转换为unsigned char类型。 0-255,超出部分会被截断 输入
num 要查找的字节数。 非负数,不超过实际内存大小。 输入

返回值

  • 成功:如果找到了字符,返回指向该字符的指针。
  • 失败:遵循开源Glibc,不返回特殊异常值。

查找是逐字节的,严格检查num个字节,不管中间是否有空字符,即该函数查找value在内存中的位置,与strchr不同。

示例

#include <stdio.h>
#include <string.h>

int main() {
    char str[] = "Hello, World!";
    char *result;
    result = (char *)memchr(str, 'o', sizeof(str));
    if (result != NULL) {
        printf("Found 'o' at index: %ld\n", (long)(result - str));
    } else {
        printf("Did not find 'o'\n");
    }
    result = (char *)memchr(str, 'x', sizeof(str));
    if (result != NULL) {
        printf("Found 'x' at index: %ld\n", (long)(result - str));
    } else {
        printf("Did not find 'x'\n");
    }
    return 0;
}

运行结果:

Found 'o' at index: 4
Did not find 'x'

memcmp

函数功能

比较两块内存区域的内容,逐字节进行比较。如果两块内存的内容不同,返回它们的差异;如果相同,则返回0。

函数定义

int memcmp(const void *ptr1, const void *ptr2, size_t num);

参数说明

参数名 描述 取值范围 输入/输出
ptr1 指向第一块内存的指针。 非空指针,指向有效内存,至少有num字节可访问。 输入
ptr2 指向第二块内存的指针。 非空指针,指向有效内存,至少有num字节可访问。 输入
num 要比较的字节数。 非负数,不超过实际内存大小。 输入

返回值

  • 成功:

    • 如果两块内存相同,返回0。
    • 如果ptr1小于ptr2,返回负值。
    • 如果ptr1大于ptr2,返回正值。
  • 失败:遵循开源Glibc,不返回特殊异常值。

比较是逐字节进行的,直到发现不同字节或比较完num字节。

示例

#include <stdio.h>
#include <string.h>

int main() {
    char str1[] = "Hello, World!";
    char str2[] = "Hello, World!";
    char str3[] = "Hello, World";

    int result1 = memcmp(str1, str2, sizeof(str1));
    if (result1 == 0) {
        printf("str1 and str2 are equal\n");
    } else {
        printf("str1 and str2 are not equal\n");
    }

    int result2 = memcmp(str1, str3, sizeof(str1));
    if (result2 != 0) {
        printf("str1 and str3 are not equal\n");
    } else {
        printf("str1 and str3 are equal\n");
    }
    return 0;
}

运行结果:

str1 and str2 are equal
str1 and str3 are not equal

memcpy

函数功能

将源内存区域的内容复制到目标内存区域。两块内存区域不允许重叠,否则会导致未定义行为。

函数定义

void *memcpy(void *dest, const void *src, size_t num);

参数说明

参数名 描述 取值范围 输入/输出
dest 指向用于存储复制内容的目标内存指针。 非空指针,指向有效内存,至少有num字节可访问。 输入/输出
src 指向要复制的数据源内存指针。 非空指针,指向有效内存,至少有num字节可访问。 输入
num 被复制的字节数。 非负数,不超过实际可分配内存大小。 输入

返回值

  • 成功:返回指向目标存储区内存的指针。
  • 失败:遵循开源Glibc,不返回特殊异常值。

如果源和目标内存区域有重叠,应该使用memmove,因为memcpy无法安全处理重叠内存。

示例

#include <stdio.h>
#include <string.h>

int main() {
    char source[] = "Hello, World!";
    char destination[20];
    memcpy(destination, source, strlen(source) + 1);

    printf("Source: %s\n", source);
    printf("Destination: %s\n", destination);
    return 0;
}

运行结果:

Source: Hello, World!
Destination: Hello, World!

memmove

函数功能

将源内存区域的内容复制到目标内存区域。两块内存区域允许重叠。

函数定义

void *memmove(void *dest, const void *src, size_t num);

参数说明

参数名 描述 取值范围 输入/输出
dest 指向用于存储复制内容的目标内存指针。 非空指针,指向有效内存,至少有num字节可访问。 输入/输出
src 指向要复制的数据源内存指针。 非空指针,指向有效内存,至少有num字节可访问。 输入
num 被复制的字节数。 非负数,不超过实际可分配内存大小。 输入

返回值

  • 成功:返回指向目标存储区内存的指针。
  • 失败:遵循开源Glibc,不返回特殊异常值。

memmove允许源和目标内存区域有重叠,相比memcpy更安全。

示例

#include <stdio.h>
#include <string.h>

int main() {
    char source[20] = "Hello, World!";
    memmove(source + 1, source, strlen(source) + 1);

    printf("Source: %s\n", source);
    return 0;
}

运行结果:

Source: HHello, World!

memset

函数功能

将指定值填充到内存区域的每个字节。通常用于初始化或清空内存区域。

函数定义

void *memset(void *ptr, int value, size_t num);

参数说明

参数名 描述 取值范围 输入/输出
ptr 指向用于存储重置内容的目标内存指针。 非空指针,指向有效内存,至少有num字节可访问。 输入/输出
value 重置的目标值。 实际会被转换为unsigned char,有效范围为0~255(超过则截断) 输入
num 被重置的字节数。 非负数,不超过ptr指向的内存大小。 输入

返回值

  • 成功:返回指向目标存储区内存的指针,返回值一般被忽略。
  • 失败:遵循开源Glibc,不返回特殊异常值。

主要用于初始化内存(如将内存设置为0或其他值)或清空数据。由于使用ZVA指令优化清零操作,因此需要注意系统ZVA块的大小。

对于memset内存清零操作,目前仅支持系统DC ZVA块大小为64B的场景,验证方法请参见ZVA块测试

ZVA块测试

#include <stdio.h>
#include <stdint.h>
int main() {
    uint64_t dczid;
    // 使用内联汇编读取dczid_el0
    asm volatile("mrs %0, dczid_el0" : "=r"(dczid));
    if (dczid & 0x10) {
        printf("DC ZVA not supported.\n");
    } else {
        uint32_t bs = dczid & 0xF;
        uint32_t size = 1 << (bs + 2);  // 块大小 = 2^(bs+2) 字节
        printf("DC ZVA block size: %u bytes\n", size);
    }
    return 0;
}

编译并执行上述内容。

gcc test_zva.c -o test_zva
./test_zva

运行结果如下所示。

DC ZVA block size: 64 bytes

示例

#include <stdio.h>
#include <string.h>

int main() {
    char byteArr[10];
    memset(byteArr, 'A', sizeof(byteArr));
    for(int i = 0; i < sizeof(byteArr); i++) {
        printf("%c ", byteArr[i]);
    }
    printf("\n");
    return 0;
}

运行结果:

A A A A A A A A A A 

gettimeofday

函数功能

获取当前系统的时间,返回自1970年1月1日以来的秒数和微秒数。该函数适用于获取高精度的时间戳。

函数定义

int gettimeofday(struct timeval *tv, struct timezone *tz);

参数说明

参数名 描述 取值范围 输入/输出
tv 指向struct timeval的指针,返回当前时间的秒数和微秒数。 非空timeval结构体 输入/输出
tz 指向struct timezone的指针,通常在现代系统中不再使用,因此通常设为NULL。 NULL 输入

返回值

  • 成功:返回0。
  • 失败:遵循开源Glibc,不返回特殊异常值。

gettimeofday提供的时间精度为微秒级。

示例

#include <stdio.h>
#include <sys/time.h>
#include <time.h>

int main() {
    struct timeval tv;
    struct timezone *tz;
    int seconds;
    float micros;
    tz = NULL;
    gettimeofday(&tv, tz);
    seconds = tv.tv_sec;
    micros = tv.tv_usec;
  
    printf("当前时间(秒数):%ld\n", seconds);
    double timestamp = seconds + micros / 1.0e6;
    printf("高精度时间戳(秒数和微秒数):%f\n", timestamp);
    return 0;
}

运行结果:

结果:
当前时间(秒数):***
高精度时间戳(秒数和微秒数):***

clock_gettime

函数功能

获取纳秒级精度时间,CLOCK_REALTIME时钟源返回自1970年1月1日以来的秒数和纳秒数。该函数适用于获取高精度的时间戳。

函数定义

int clock_gettime(clockid_t clk_id,struct timespec *tp);

参数说明

参数名 描述 取值范围 输入/输出
clk_id 时钟源模式 目前仅优化支持CLOCK_REALTIME 输入
tp 指向struct timespec的指针,用于存储获取的时间值。 非空timespec结构体 输入/输出

返回值

  • 成功:返回0。
  • 失败:若tp为空,返回KPGLIBC_STS_PARAMETER_ERR错误码。

clock_gettime提供的时间精度为纳秒级。

示例

#include <stdio.h>
#include <time.h>

int main() 
{
    struct timespec ts;
    if (clock_gettime(CLOCK_REALTIME, &ts)  != 0) {
        perror("clock_gettime error");
        return 1;
    }
    printf("当前时间:%ld 秒 %ld 纳秒\n", ts.tv_sec, ts.tv_nsec);
    return 0;
}

运行结果:

当前时间:***秒 ***纳秒