File: switch.c

package info (click to toggle)
rtlinux 2.0rel-1
  • links: PTS
  • area: main
  • in suites: potato
  • size: 2,068 kB
  • ctags: 1,178
  • sloc: ansic: 7,169; makefile: 779; sh: 89
file content (81 lines) | stat: -rw-r--r-- 1,592 bytes parent folder | download
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
#include <linux/smp.h>
#include <asm/system.h>
#include <linux/tasks.h>

#include "../include/rtl_conf.h"

#include "../include/rtl_sched.h"
#include <rtl_core.h>
#include <linux/cons.h>

#ifdef CONFIG_RTL_FP_SUPPORT
int is_set_TS(void)
{
	int current_TS;
	__asm__("movl %%cr0,%%eax;andl $8,%%eax;movl %%eax,%0" \
			:"=m" (current_TS)/*output*/ \
			: /* no inputs */ \
			:"ax");
	return current_TS;
}


void rtl_fpu_save (schedule_t *s, RTL_THREAD_STRUCT *current_t)
{
/* 	if (s->rtl_current == &(s->rtl_linux_task)) { */ /* not good */
	if (current_t == &(s->rtl_linux_task)) {
		s->sched_user[0] = is_set_TS();
		clts();
	}
	__asm__("fnsave %0" : "=m" (current_t->fpu_regs));
}


void rtl_fpu_restore (schedule_t *s,RTL_THREAD_STRUCT *current_t) {
	clts (); /* just in case */
	__asm__("frstor %0" : "=m" (current_t->fpu_regs));
	if ((current_t == &(s->rtl_linux_task)) && s->sched_user[0])
	{
		stts();
	}
}


/*
static int rt_is_fpu_used ()
{
	for (t = RTL_THREAD_STRUCTs; t; t = t->next) {
		if (t -> uses_fp) {
			return 1;
		}
	}
	return 0;
}
*/


void rtl_task_init_fpu (RTL_THREAD_STRUCT *t, RTL_THREAD_STRUCT *fpu_owner)
{
	int was_set_TS;
	/* we  must save/restore the fpu state*/
	if (fpu_owner) {
		if ((was_set_TS = is_set_TS())) {
			clts();
		}
		__asm__("fnsave %0" : "=m" (fpu_owner -> fpu_regs));
		__asm__("fninit");
		__asm__("fnsave %0" : "=m" (t->fpu_regs));
		__asm__("frstor %0" : "=m" (fpu_owner -> fpu_regs));
		if (was_set_TS) {
			stts();
		}
	} else {
		clts ();
		__asm__("fninit");
/* 		fpu_owner = t; */
	}
	return ;
}

#endif /* CONFIG_RTL_FP_SUPPORT */