tapasco_scheduler.c 4.15 KB
Newer Older
1
2
3
//
// Copyright (C) 2014 Jens Korinth, TU Darmstadt
//
4
// This file is part of Tapasco (TPC).
5
//
6
// Tapasco is free software: you can redistribute it and/or modify
7
8
9
10
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
11
// Tapasco is distributed in the hope that it will be useful,
12
13
14
15
16
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
17
// along with Tapasco.  If not, see <http://www.gnu.org/licenses/>.
18
//
19
/** @file	tapasco_scheduler.c
20
21
22
23
24
 *  @brief	Primitive scheduler.
 *  @author	J. Korinth, TU Darmstadt (jk@esa.cs.tu-darmstadt.de)
 **/
#include <unistd.h>
#include <assert.h>
25
26
27
28
29
#include <tapasco_scheduler.h>
#include <tapasco_functions.h>
#include <tapasco_address_map.h>
#include <tapasco_device.h>
#include <tapasco_logging.h>
30
31
#include <platform_api.h>

32
33
34
35
36
tapasco_res_t tapasco_scheduler_launch(
		tapasco_dev_ctx_t *dev_ctx,
		tapasco_jobs_t *jobs,
		tapasco_functions_t *functions,
		tapasco_job_id_t const j_id)
37
{
38
39
40
	tapasco_res_t result = TAPASCO_SUCCESS;
	tapasco_func_id_t const f_id = tapasco_jobs_get_func_id(jobs, j_id);
	tapasco_func_slot_id_t slot_id;
41
42
43
44

	LOG(LALL_SCHEDULER, "job %lu: launching for function %lu, acquiring function ... ",
			(unsigned long)j_id, (unsigned long)f_id);

45
	while ((slot_id = tapasco_functions_acquire(functions, f_id)) < 0)
46
47
48
49
50
		usleep(250);

	LOG(LALL_SCHEDULER, "job %lu: got function %lu",
			(unsigned long)j_id, (unsigned long)f_id);

51
	assert(slot_id >= 0 && slot_id < TAPASCO_MAX_INSTANCES);
52

53
	tapasco_jobs_set_state(jobs, j_id, TAPASCO_JOB_STATE_SCHEDULED);
54
55
	// printf("job_id %d runs on slot_id %d\n", j_id, slot_id);

56
	uint32_t const num_args = tapasco_jobs_arg_count(jobs, j_id);
57
	for (uint32_t a = 0; a < num_args; ++a) {
58
		tapasco_handle_t h = tapasco_address_map_func_arg_register(
59
60
61
62
				dev_ctx,
				slot_id,
				a);

63
		int const is64 = tapasco_jobs_is_arg_64bit(jobs, j_id, a);
64
		if (is64) {
65
			uint64_t v = tapasco_jobs_get_arg64(jobs, j_id, a);
66
67
68
			LOG(LALL_SCHEDULER, "job %lu: writing 64b arg #%u = 0x%08lx to 0x%08x",
				(unsigned long)j_id, a, (unsigned long)v, (unsigned)h);
			if (platform_write_ctl(h, sizeof(v), &v, PLATFORM_CTL_FLAGS_NONE) != PLATFORM_SUCCESS)
69
				return TAPASCO_FAILURE;
70
		} else {
71
			uint32_t v = tapasco_jobs_get_arg32(jobs, j_id, a);
72
73
74
			LOG(LALL_SCHEDULER, "job %lu: writing 32b arg #%u = 0x%08lx to 0x%08x",
				(unsigned long)j_id, a, (unsigned long)v, (unsigned)h);
			if (platform_write_ctl(h, sizeof(v), &v, PLATFORM_CTL_FLAGS_NONE) != PLATFORM_SUCCESS)
75
				return TAPASCO_FAILURE;
76
77
78
79
		}
	}

	// now write start command and wait until finished
80
81
	tapasco_handle_t const ctl = tapasco_address_map_func_reg(
			dev_ctx, slot_id, TAPASCO_FUNC_REG_CONTROL);
82
83
84
85
86
	// printf("job %d stl register at 0x%08x\n", j_id, (unsigned int)ctl);

	LOG(LALL_SCHEDULER, "job %lu: launching and waiting ...", (unsigned long)j_id);

	uint32_t start_cmd = 1;
87
	tapasco_jobs_set_state(jobs, j_id, TAPASCO_JOB_STATE_RUNNING);
88
89
	if ( platform_write_ctl_and_wait(ctl, sizeof(start_cmd), &start_cmd,
			slot_id, PLATFORM_CTL_FLAGS_NONE) != PLATFORM_SUCCESS)
90
		return TAPASCO_FAILURE;
91
92
93
94

	LOG(LALL_SCHEDULER, "job %lu: returned from waiting", (unsigned long)j_id);

	uint64_t ret = 0;
95
	tapasco_handle_t const rh = tapasco_address_map_func_reg(dev_ctx, slot_id, TAPASCO_FUNC_REG_RETURN);
96
97

	if (platform_read_ctl(rh, sizeof(ret), &ret, PLATFORM_CTL_FLAGS_NONE) != PLATFORM_SUCCESS)
98
99
		return TAPASCO_FAILURE;
	tapasco_jobs_set_return(jobs, j_id, sizeof(ret), &ret);
100
101
102
103
	LOG(LALL_SCHEDULER, "job %lu: read result value 0x%08lx",
			(unsigned long)j_id, (unsigned long)ret);

	// ack the interrupt
104
105
	if (platform_write_ctl(tapasco_address_map_func_reg(dev_ctx, slot_id,
			TAPASCO_FUNC_REG_IAR), sizeof(start_cmd), &start_cmd,
106
			PLATFORM_CTL_FLAGS_NONE) != PLATFORM_SUCCESS)
107
		return TAPASCO_FAILURE;
108
109

	// release the function
110
	tapasco_functions_release(functions, slot_id);
111

112
	tapasco_jobs_set_state(jobs, j_id, TAPASCO_JOB_STATE_FINISHED);
113
114
115

	return result;
}