blob: ccbd0685b64078575744f6632040c1ba5e632f58 (
plain)
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
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
/* Copyright (c) 2013, Linaro Limited
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <sched.h>
#include <odp_thread.h>
#include <odp_internal.h>
#include <odp_atomic.h>
#include <odp_config.h>
#include <odp_debug_internal.h>
#include <odp_shared_memory.h>
#include <odp_align.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int thr_id;
int cpu;
} thread_state_t;
typedef struct {
thread_state_t thr[ODP_CONFIG_MAX_THREADS];
odp_atomic_u32_t num;
odp_atomic_u32_t next_id;
} thread_globals_t;
/* Globals */
static thread_globals_t *thread_globals;
/* Thread local */
static __thread thread_state_t *this_thread;
int odp_thread_init_global(void)
{
odp_shm_t shm;
shm = odp_shm_reserve("odp_thread_globals",
sizeof(thread_globals_t),
ODP_CACHE_LINE_SIZE, 0);
thread_globals = odp_shm_addr(shm);
if (thread_globals == NULL)
return -1;
memset(thread_globals, 0, sizeof(thread_globals_t));
odp_atomic_init_u32(&thread_globals->next_id, 0);
odp_atomic_init_u32(&thread_globals->num, 0);
return 0;
}
static int thread_id(void)
{
uint32_t id;
int cpu;
id = odp_atomic_fetch_inc_u32(&thread_globals->next_id);
if (id >= ODP_CONFIG_MAX_THREADS) {
ODP_ERR("Too many threads\n");
return -1;
}
odp_atomic_inc_u32(&thread_globals->num);
cpu = sched_getcpu();
if (cpu < 0) {
ODP_ERR("getcpu failed\n");
return -1;
}
thread_globals->thr[id].thr_id = id;
thread_globals->thr[id].cpu = cpu;
return id;
}
int odp_thread_init_local(void)
{
int id;
id = thread_id();
if (id < 0)
return -1;
this_thread = &thread_globals->thr[id];
return 0;
}
int odp_thread_term_local(void)
{
uint32_t num;
num = odp_atomic_fetch_dec_u32(&thread_globals->num);
ODP_ASSERT(num > 0, "Number of threads should be > 0");
return num - 1; /* return a number of threads left */
}
int odp_thread_id(void)
{
return this_thread->thr_id;
}
int odp_thread_cpu(void)
{
return this_thread->cpu;
}
|