Skip to content

Commit

Permalink
chore(doc): update function template docs
Browse files Browse the repository at this point in the history
  • Loading branch information
Water-Melon committed Jan 19, 2024
1 parent 34c9148 commit edc797c
Show file tree
Hide file tree
Showing 3 changed files with 405 additions and 1 deletion.
202 changes: 202 additions & 0 deletions docs/book/cn/func.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,205 @@ exit a.c bcd 10
```

正如`MLN_FUNC`中说明的,使用这个宏定义函数时,实际的函数会被添加`__`前缀,而原本给出的名字则是一个包装器。



### 函数耗时示例

首先创建两个文件`span.c``span.h`

#### span.h

```c
#include <sys/time.h>
#include "mln_array.h"

typedef struct mln_span_s {
struct timeval begin;
struct timeval end;
const char *file;
const char *func;
int line;
mln_array_t subspans;
struct mln_span_s *parent;
} mln_span_t;

extern int mln_span_start(void);
extern void mln_span_stop(void);
extern void mln_span_dump(void);
extern void mln_span_release(void);
```
#### span.c
```c
#include <stdlib.h>
#include <string.h>
#include "span.h"
#include "mln_stack.h"
#define MLN_FUNC_FLAG
#include "mln_func.h"
static mln_stack_t *callstack = NULL;
static mln_span_t *root = NULL;
static void mln_span_entry(const char *file, const char *func, int line);
static void mln_span_exit(const char *file, const char *func, int line);
static mln_span_t *mln_span_new(mln_span_t *parent, const char *file, const char *func, int line);
static void mln_span_free(mln_span_t *s);
static mln_span_t *mln_span_new(mln_span_t *parent, const char *file, const char *func, int line)
{
mln_span_t *s;
struct mln_array_attr attr;
if (parent != NULL) {
s = (mln_span_t *)mln_array_push(&parent->subspans);
} else {
s = (mln_span_t *)malloc(sizeof(mln_span_t));
}
if (s == NULL) return NULL;
memset(&s->begin, 0, sizeof(struct timeval));
memset(&s->end, 0, sizeof(struct timeval));
s->file = file;
s->func = func;
s->line = line;
attr.pool = NULL;
attr.pool_alloc = NULL;
attr.pool_free = NULL;
attr.free = (array_free)mln_span_free;
attr.size = sizeof(mln_span_t);
attr.nalloc = 7;
if (mln_array_init(&s->subspans, &attr) < 0) {
if (parent == NULL) free(s);
return NULL;
}
s->parent = parent;
return s;
}
static void mln_span_free(mln_span_t *s)
{
if (s == NULL) return;
mln_array_destroy(&s->subspans);
if (s->parent == NULL) free(s);
}
int mln_span_start(void)
{
struct mln_stack_attr sattr;
mln_func_entry_callback_set(mln_span_entry);
mln_func_exit_callback_set(mln_span_exit);
sattr.free_handler = NULL;
sattr.copy_handler = NULL;
if ((callstack = mln_stack_init(&sattr)) == NULL)
return -1;
return 0;
}
void mln_span_stop(void)
{
mln_func_entry_callback_set(NULL);
mln_func_exit_callback_set(NULL);
mln_stack_destroy(callstack);
}
void mln_span_release(void)
{
mln_span_free(root);
}
static void mln_span_format_dump(mln_span_t *span, int blanks)
{
int i;
mln_span_t *sub;
for (i = 0; i < blanks; ++i)
printf(" ");
printf("| %s at %s:%d takes %lu (us)\n", \
span->func, span->file, span->line, \
(span->end.tv_sec * 1000000 + span->end.tv_usec) - (span->begin.tv_sec * 1000000 + span->begin.tv_usec));
for (i = 0; i < mln_array_nelts(&(span->subspans)); ++i) {
sub = ((mln_span_t *)mln_array_elts(&(span->subspans))) + i;
mln_span_format_dump(sub, blanks + 2);
}
}
void mln_span_dump(void)
{
if (root != NULL)
mln_span_format_dump(root, 0);
}
static void mln_span_entry(const char *file, const char *func, int line)
{
mln_span_t *span;
if ((span = mln_span_new(mln_stack_top(callstack), file, func, line)) == NULL) {
fprintf(stderr, "new span failed\n");
exit(1);
}
if (mln_stack_push(callstack, span) < 0) {
fprintf(stderr, "push span failed\n");
exit(1);
}
if (root == NULL) root = span;
gettimeofday(&span->begin, NULL);
}
static void mln_span_exit(const char *file, const char *func, int line)
{
mln_span_t *span = mln_stack_pop(callstack);
if (span == NULL) {
fprintf(stderr, "call stack crashed\n");
exit(1);
}
gettimeofday(&span->end, NULL);
}
```

接下来,创建一个开发者自定义的程序`a.c`

```c
#include "span.h"
#define MLN_FUNC_FLAG
#include "mln_func.h"

MLN_FUNC(int, abc, (int a, int b), (a, b), {
return a + b;
})

MLN_FUNC(static int, bcd, (int a, int b), (a, b), {
return abc(a, b) + abc(a, b);
})

int main(void)
{
mln_span_start();
bcd(1, 2);
mln_span_stop();
mln_span_dump();
mln_span_release();
return 0;
}
```
编译程序:
```bash
cc -o a a.c span.c -I /usr/local/melon/include/ -L /usr/local/melon/lib/ -lmelon -ggdb
```

执行一下,可以看到如下输出:

```
| bcd at a.c:13 takes 1 (us)
| abc at a.c:9 takes 0 (us)
| abc at a.c:9 takes 0 (us)
```

2 changes: 1 addition & 1 deletion docs/book/cn/template.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@

在Melon中,利用C语言宏实现了如下模板组件:

- 函数定义
- 函数模板
Loading

0 comments on commit edc797c

Please sign in to comment.