OSDN Git Service

Merge branch 'suikan_experimental2' into develop
[trx-305dsp/dsp.git] / hirado / kernel / systask / cxxrt.c
1 /*
2  *  TOPPERS/JSP Kernel
3  *      Toyohashi Open Platform for Embedded Real-Time Systems/
4  *      Just Standard Profile Kernel
5  *
6  *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7  *                              Toyohashi Univ. of Technology, JAPAN
8  *  Copyright (C) 2003-2004 by Takagi Nobuhisa
9  *
10  *  上記著作権者は,以下の (1)〜(4) の条件か,Free Software Foundation
11  *  によって公表されている GNU General Public License の Version 2 に記
12  *  述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
13  *  を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
14  *  利用と呼ぶ)することを無償で許諾する.
15  *  (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
16  *      権表示,この利用条件および下記の無保証規定が,そのままの形でソー
17  *      スコード中に含まれていること.
18  *  (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
19  *      用できる形で再配布する場合には,再配布に伴うドキュメント(利用
20  *      者マニュアルなど)に,上記の著作権表示,この利用条件および下記
21  *      の無保証規定を掲載すること.
22  *  (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
23  *      用できない形で再配布する場合には,次のいずれかの条件を満たすこ
24  *      と.
25  *    (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
26  *        作権表示,この利用条件および下記の無保証規定を掲載すること.
27  *    (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
28  *        報告すること.
29  *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
30  *      害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
31  *
32  *  本ソフトウェアは,無保証で提供されているものである.上記著作権者お
33  *  よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
34  *  含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
35  *  接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
36  *
37  *  @(#) $Id: cxxrt.c,v 1.2 2010/05/02 04:43:52 suikan Exp $
38  */
39 #include "../kernel/jsp_kernel.h"
40 #include "../kernel/task.h"
41 #include "kernel_id.h"
42 extern void * malloc ( size_t size );
43
44 typedef int _toppers_cxxrt_sync_t;
45 typedef volatile char _toppers_cxxrt_once_t;
46
47 static inline int _get_tid()
48 {
49     return runtsk - tcb_table + TMIN_TSKID;
50 }
51
52 /*
53  *  For Syncronization
54  */
55 int _toppers_cxxrt_lock(_toppers_cxxrt_sync_t *sync)
56 {
57     if (iniflg)
58         dis_dsp();
59     return 0;
60 }
61
62 int _toppers_cxxrt_trylock(_toppers_cxxrt_sync_t *sync)
63 {
64     return _toppers_cxxrt_lock(sync);
65 }
66
67 int _toppers_cxxrt_unlock(_toppers_cxxrt_sync_t *sync)
68 {
69     if (iniflg)
70         ena_dsp();
71     return 0;
72 }
73
74 int _toppers_cxxrt_get_tskid(void)
75 {
76     return iniflg ? _get_tid() : 0;
77 }
78
79 /*
80  *  For recursive semaphore lock
81  */
82 static ID cxxrt_holder;
83 static UINT cxxrt_counter;
84
85 static inline void _toppers_cxxrt_recursive_semaphore_lock(ID semid)
86 {
87     if (iniflg && !sns_dsp())
88     {
89         ID tskid;
90         tskid = _get_tid();
91
92         if (cxxrt_holder != tskid)
93         {
94             wai_sem(semid);
95             cxxrt_holder = tskid;
96         }
97         ++cxxrt_counter;
98     }
99 }
100
101 static inline void _toppers_cxxrt_recursive_semaphore_unlock(ID semid)
102 {
103     if (iniflg && !sns_dsp())
104     {
105         if (--cxxrt_counter == 0)
106         {
107             cxxrt_holder = 0;
108             sig_sem(semid);
109         }
110     }
111 }
112
113
114 /*
115  *  For function call once
116  */
117 int _toppers_cxxrt_once(_toppers_cxxrt_once_t *once, void (*func)(void))
118 {
119     if (!*once)
120     {
121         static _toppers_cxxrt_sync_t sync;
122
123         _toppers_cxxrt_recursive_semaphore_lock(_CXXRT_SEM);
124         if (!*once)
125         {
126             (*func)();
127             *once = 1;
128         }
129         _toppers_cxxrt_recursive_semaphore_unlock(_CXXRT_SEM);
130     }
131     return 0;
132 }
133
134
135 /*
136  *  For task-local storage
137  */
138 #ifndef CXXRT_KEY_MAX
139 #define CXXRT_KEY_MAX   2
140 #endif
141
142 struct _toppers_cxxrt_tls
143 {
144     void **data;
145     void (*dtor)(void*);
146 };
147
148 extern const ID tmax_tskid;
149
150 static void **tls_data[CXXRT_KEY_MAX];
151 static struct _toppers_cxxrt_tls tls[CXXRT_KEY_MAX];
152
153 int _toppers_cxxrt_key_create(struct _toppers_cxxrt_tls **key, void (*dtor)(void*))
154 {
155     struct _toppers_cxxrt_tls *p;
156
157     for (p = &tls[0]; p < &tls[CXXRT_KEY_MAX]; p++)
158     {
159         if (p->data == NULL)
160         {
161             p->data = tls_data[p - &tls[0]];
162             p->dtor = dtor;
163             *key = p;
164             return 0;
165         }
166     }
167     return -1;
168 }
169
170 int _toppers_cxxrt_key_delete(struct _toppers_cxxrt_tls *key)
171 {
172     int i;
173
174     for (i = 0; i <= tmax_tskid; i++)
175     {
176         if (key->dtor != 0)
177             (*key->dtor)(key->data[i]);
178     }
179     key->data = NULL;
180     key->dtor = 0;
181     return 0;
182 }
183
184 /* JSP 1.4との互換性のために_toppers_cxxrt_reset_specificを残しておく */
185 void _toppers_cxxrt_reset_specific(void)
186 {
187 }
188
189 void _toppers_cxxrt_init(void)
190 {
191     int i, tmax = tmax_tskid + 1;
192     void **p = (void**)malloc(sizeof(void*) * CXXRT_KEY_MAX * tmax);
193
194     for (i = 0; i < CXXRT_KEY_MAX * tmax; i++)
195         p[i] = NULL;
196     for (i = 0; i < CXXRT_KEY_MAX; i++)
197         tls_data[i] = p + i * tmax;
198 }
199