libperf: Adopt perf_mmap__consume() function from tools/perf
[linux-2.6-block.git] / tools / perf / lib / mmap.c
CommitLineData
353120b4 1// SPDX-License-Identifier: GPL-2.0
32c261c0 2#include <sys/mman.h>
7728fa0c
JO
3#include <linux/ring_buffer.h>
4#include <linux/perf_event.h>
5#include <perf/mmap.h>
353120b4 6#include <internal/mmap.h>
bf59b305 7#include <internal/lib.h>
80e53d11 8#include <linux/kernel.h>
353120b4 9
80e53d11
JO
10void perf_mmap__init(struct perf_mmap *map, bool overwrite,
11 libperf_unmap_cb_t unmap_cb)
353120b4
JO
12{
13 map->fd = -1;
14 map->overwrite = overwrite;
80e53d11 15 map->unmap_cb = unmap_cb;
353120b4
JO
16 refcount_set(&map->refcnt, 0);
17}
bf59b305
JO
18
19size_t perf_mmap__mmap_len(struct perf_mmap *map)
20{
21 return map->mask + 1 + page_size;
22}
32c261c0
JO
23
24int perf_mmap__mmap(struct perf_mmap *map, struct perf_mmap_param *mp,
25 int fd, int cpu)
26{
27 map->prev = 0;
28 map->mask = mp->mask;
29 map->base = mmap(NULL, perf_mmap__mmap_len(map), mp->prot,
30 MAP_SHARED, fd, 0);
31 if (map->base == MAP_FAILED) {
32 map->base = NULL;
33 return -1;
34 }
35
36 map->fd = fd;
37 map->cpu = cpu;
38 return 0;
39}
e75710f0 40
59d7ea62
JO
41void perf_mmap__munmap(struct perf_mmap *map)
42{
43 if (map && map->base != NULL) {
44 munmap(map->base, perf_mmap__mmap_len(map));
45 map->base = NULL;
46 map->fd = -1;
47 refcount_set(&map->refcnt, 0);
48 }
80e53d11
JO
49 if (map && map->unmap_cb)
50 map->unmap_cb(map);
59d7ea62
JO
51}
52
e75710f0
JO
53void perf_mmap__get(struct perf_mmap *map)
54{
55 refcount_inc(&map->refcnt);
56}
80e53d11
JO
57
58void perf_mmap__put(struct perf_mmap *map)
59{
60 BUG_ON(map->base && refcount_read(&map->refcnt) == 0);
61
62 if (refcount_dec_and_test(&map->refcnt))
63 perf_mmap__munmap(map);
64}
7728fa0c
JO
65
66static inline void perf_mmap__write_tail(struct perf_mmap *md, u64 tail)
67{
68 ring_buffer_write_tail(md->base, tail);
69}
70
71u64 perf_mmap__read_head(struct perf_mmap *map)
72{
73 return ring_buffer_read_head(map->base);
74}
75
76static bool perf_mmap__empty(struct perf_mmap *map)
77{
78 struct perf_event_mmap_page *pc = map->base;
79
80 return perf_mmap__read_head(map) == map->prev && !pc->aux_size;
81}
82
83void perf_mmap__consume(struct perf_mmap *map)
84{
85 if (!map->overwrite) {
86 u64 old = map->prev;
87
88 perf_mmap__write_tail(map, old);
89 }
90
91 if (refcount_read(&map->refcnt) == 1 && perf_mmap__empty(map))
92 perf_mmap__put(map);
93}