aboutsummaryrefslogtreecommitdiff
path: root/platform/linux-generic/odp_linux.c
blob: 6e2b4481455bee4d378b845df9a99c3104e170c0 (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
/* 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 <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>

#include <helper/odp_linux.h>
#include <odp_internal.h>
#include <odp_thread.h>
#include <odp_init.h>
#include <odp_system_info.h>
#include <odp_debug.h>


typedef struct {
	int thr_id;
	void *(*start_routine) (void *);
	void *arg;

} odp_start_args_t;


static void *odp_run_start_routine(void *arg)
{
	odp_start_args_t *start_args = arg;

	/* ODP thread local init */
	if (odp_init_local(start_args->thr_id)) {
		ODP_ERR("Local init failed for thread: %d\n",
			start_args->thr_id);
		return NULL;
	}

	return start_args->start_routine(start_args->arg);
}


void odp_linux_pthread_create(odp_linux_pthread_t *thread_tbl, int num,
		int first_core, void *(*start_routine) (void *), void *arg)
{
	int i;
	cpu_set_t cpu_set;
	odp_start_args_t *start_args;
	int core_count;
	int cpu;

	core_count = odp_sys_core_count();

	assert((first_core >= 0) && (first_core < core_count));
	assert((num >= 0) && (num <= core_count));

	memset(thread_tbl, 0, num * sizeof(odp_linux_pthread_t));

	for (i = 0; i < num; i++) {
		pthread_attr_init(&thread_tbl[i].attr);

		CPU_ZERO(&cpu_set);

		cpu = (first_core + i) % core_count;
		CPU_SET(cpu, &cpu_set);

		pthread_attr_setaffinity_np(&thread_tbl[i].attr,
					    sizeof(cpu_set_t), &cpu_set);

		start_args = malloc(sizeof(odp_start_args_t));
		memset(start_args, 0, sizeof(odp_start_args_t));
		start_args->start_routine = start_routine;
		start_args->arg           = arg;

		start_args->thr_id        = odp_thread_create(cpu);

		pthread_create(&thread_tbl[i].thread, &thread_tbl[i].attr,
			       odp_run_start_routine, start_args);
	}
}


void odp_linux_pthread_join(odp_linux_pthread_t *thread_tbl, int num)
{
	int i;

	for (i = 0; i < num; i++) {
		/* Wait thread to exit */
		pthread_join(thread_tbl[i].thread, NULL);
	}
}