1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
13:
14: 15: 16: 17:
18:
19: #include "kernel.h"
20: #include "klock.h"
21: #include "wait.h"
22: #include "check.h"
23: #include "mempfix.h"
24:
25: #if USE_FIX_MEMORYPOOL
26:
27: Noinit(EXPORT MPFCB knl_mpfcb_table[NUM_MPFID]);
28: Noinit(EXPORT QUEUE knl_free_mpfcb);
29:
30:
31: 32: 33:
34: EXPORT ER knl_fix_memorypool_initialize( void )
35: {
36: MPFCB *mpfcb, *end;
37:
38:
39: if ( NUM_MPFID < 1 ) {
40: return E_SYS;
41: }
42:
43:
44: QueInit(&knl_free_mpfcb);
45: end = knl_mpfcb_table + NUM_MPFID;
46: for ( mpfcb = knl_mpfcb_table; mpfcb < end; mpfcb++ ) {
47: mpfcb->mpfid = 0;
48: knl_InitOBJLOCK(&mpfcb->lock);
49: QueInsert(&mpfcb->wait_queue, &knl_free_mpfcb);
50: }
51:
52: return E_OK;
53: }
54:
55:
56: 57: 58:
59: SYSCALL ID tk_cre_mpf( CONST T_CMPF *pk_cmpf )
60: {
61: #if CHK_RSATR
62: const ATR VALID_MPFATR = {
63: TA_TPRI
64: |TA_RNG3
65: |TA_USERBUF
66: #if USE_OBJECT_NAME
67: |TA_DSNAME
68: #endif
69: };
70: #endif
71: MPFCB *mpfcb;
72: ID mpfid;
73: W blfsz, mpfsz;
74: void *mempool;
75:
76: CHECK_RSATR(pk_cmpf->mpfatr, VALID_MPFATR);
77: CHECK_PAR(pk_cmpf->mpfcnt > 0);
78: CHECK_PAR(pk_cmpf->blfsz > 0);
79: #if !USE_IMALLOC
80:
81: CHECK_PAR((pk_cmpf->mpfatr & TA_USERBUF) != 0);
82: #endif
83: CHECK_DISPATCH();
84:
85: blfsz = (W)MINSZ(pk_cmpf->blfsz);
86: mpfsz = blfsz * pk_cmpf->mpfcnt;
87:
88: #if USE_IMALLOC
89: if ( (pk_cmpf->mpfatr & TA_USERBUF) != 0 ) {
90:
91: if ( blfsz != pk_cmpf->blfsz ) {
92: return E_PAR;
93: }
94:
95: mempool = pk_cmpf->bufptr;
96: } else {
97:
98: mempool = knl_Imalloc((UW)mpfsz);
99: if ( mempool == NULL ) {
100: return E_NOMEM;
101: }
102: }
103: #else
104:
105: if ( blfsz != pk_cmpf->blfsz ) {
106: return E_PAR;
107: }
108:
109: mempool = pk_cmpf->bufptr;
110: #endif
111:
112:
113: DISABLE_INTERRUPT;
114: mpfcb = (MPFCB*)QueRemoveNext(&knl_free_mpfcb);
115: ENABLE_INTERRUPT;
116:
117: if ( mpfcb == NULL ) {
118: #if USE_IMALLOC
119: if ( (pk_cmpf->mpfatr & TA_USERBUF) == 0 ) {
120: knl_Ifree(mempool);
121: }
122: #endif
123: return E_LIMIT;
124: }
125:
126: knl_LockOBJ(&mpfcb->lock);
127: mpfid = ID_MPF(mpfcb - knl_mpfcb_table);
128:
129:
130: QueInit(&mpfcb->wait_queue);
131: mpfcb->exinf = pk_cmpf->exinf;
132: mpfcb->mpfatr = pk_cmpf->mpfatr;
133: mpfcb->mpfcnt = mpfcb->frbcnt = pk_cmpf->mpfcnt;
134: mpfcb->blfsz = blfsz;
135: mpfcb->mpfsz = mpfsz;
136: mpfcb->unused = mpfcb->mempool = mempool;
137: mpfcb->freelist = NULL;
138: #if USE_OBJECT_NAME
139: if ( (pk_cmpf->mpfatr & TA_DSNAME) != 0 ) {
140: knl_strncpy((char*)mpfcb->name, (char*)pk_cmpf->dsname, OBJECT_NAME_LENGTH);
141: }
142: #endif
143:
144: mpfcb->mpfid = mpfid;
145: knl_UnlockOBJ(&mpfcb->lock);
146:
147: return mpfid;
148: }
149:
150: #ifdef USE_FUNC_TK_DEL_MPF
151: 152: 153:
154: SYSCALL ER tk_del_mpf( ID mpfid )
155: {
156: MPFCB *mpfcb;
157: void *mempool = NULL;
158: ATR memattr = 0;
159: ER ercd = E_OK;
160:
161: CHECK_MPFID(mpfid);
162: CHECK_DISPATCH();
163:
164: mpfcb = get_mpfcb(mpfid);
165:
166: knl_LockOBJ(&mpfcb->lock);
167: if ( mpfcb->mpfid == 0 ) {
168: ercd = E_NOEXS;
169: } else {
170: DISABLE_INTERRUPT;
171: mempool = mpfcb->mempool;
172: memattr = mpfcb->mpfatr;
173:
174:
175: knl_wait_delete(&mpfcb->wait_queue);
176:
177:
178: QueInsert(&mpfcb->wait_queue, &knl_free_mpfcb);
179: mpfcb->mpfid = 0;
180: ENABLE_INTERRUPT;
181: }
182: knl_UnlockOBJ(&mpfcb->lock);
183:
184: #if USE_IMALLOC
185: if ( (mempool != NULL) && ((memattr & TA_USERBUF) == 0) ) {
186: knl_Ifree(mempool);
187: }
188: #endif
189:
190: return ercd;
191: }
192: #endif
193:
194: 195: 196:
197: LOCAL void knl_mpf_chg_pri( TCB *tcb, INT oldpri )
198: {
199: MPFCB *mpfcb;
200:
201: mpfcb = get_mpfcb(tcb->wid);
202: knl_gcb_change_priority((GCB*)mpfcb, tcb);
203: }
204:
205: 206: 207:
208: LOCAL CONST WSPEC knl_wspec_mpf_tfifo = { TTW_MPF, NULL, NULL };
209: LOCAL CONST WSPEC knl_wspec_mpf_tpri = { TTW_MPF, knl_mpf_chg_pri, NULL };
210:
211: 212: 213:
214: SYSCALL ER tk_get_mpf( ID mpfid, void **p_blf, TMO tmout )
215: {
216: MPFCB *mpfcb;
217: FREEL *free;
218: ER ercd = E_OK;
219:
220: CHECK_MPFID(mpfid);
221: CHECK_TMOUT(tmout);
222: CHECK_DISPATCH();
223:
224: mpfcb = get_mpfcb(mpfid);
225:
226: knl_LockOBJ(&mpfcb->lock);
227: if ( mpfcb->mpfid == 0 ) {
228: ercd = E_NOEXS;
229: goto error_exit;
230: }
231:
232:
233: if ( mpfcb->frbcnt <= 0 ) {
234: goto wait_mpf;
235: } else {
236:
237: if ( mpfcb->freelist != NULL ) {
238: free = mpfcb->freelist;
239: mpfcb->freelist = free->next;
240: *p_blf = free;
241: } else {
242: *p_blf = mpfcb->unused;
243: mpfcb->unused = (VB*)mpfcb->unused + mpfcb->blfsz;
244: }
245: mpfcb->frbcnt--;
246: }
247:
248: error_exit:
249: knl_UnlockOBJ(&mpfcb->lock);
250:
251: return ercd;
252:
253: wait_mpf:
254:
255: BEGIN_CRITICAL_SECTION;
256: knl_ctxtsk->wspec = ( (mpfcb->mpfatr & TA_TPRI) != 0 )?
257: &knl_wspec_mpf_tpri: &knl_wspec_mpf_tfifo;
258: knl_ctxtsk->wercd = &ercd;
259: knl_ctxtsk->winfo.mpf.p_blf = p_blf;
260: knl_gcb_make_wait((GCB*)mpfcb, tmout);
261:
262: knl_UnlockOBJ(&mpfcb->lock);
263: END_CRITICAL_SECTION;
264:
265: return ercd;
266: }
267:
268: 269: 270:
271: SYSCALL ER tk_rel_mpf( ID mpfid, void *blf )
272: {
273: MPFCB *mpfcb;
274: TCB *tcb;
275: FREEL *free;
276: ER ercd = E_OK;
277:
278: CHECK_MPFID(mpfid);
279: CHECK_DISPATCH();
280:
281: mpfcb = get_mpfcb(mpfid);
282:
283: knl_LockOBJ(&mpfcb->lock);
284: if ( mpfcb->mpfid == 0 ) {
285: ercd = E_NOEXS;
286: goto error_exit;
287: }
288: #if CHK_PAR
289: if ( blf < mpfcb->mempool || blf >= knl_mempool_end(mpfcb) || (((VB*)blf - (VB*)mpfcb->mempool) % mpfcb->blfsz) != 0 ) {
290: ercd = E_PAR;
291: goto error_exit;
292: }
293: #endif
294:
295: DISABLE_INTERRUPT;
296: if ( !isQueEmpty(&mpfcb->wait_queue) ) {
297: 298:
299: tcb = (TCB*)mpfcb->wait_queue.next;
300: *tcb->winfo.mpf.p_blf = blf;
301: knl_wait_release_ok(tcb);
302: ENABLE_INTERRUPT;
303: } else {
304: ENABLE_INTERRUPT;
305:
306: free = (FREEL*)blf;
307: free->next = mpfcb->freelist;
308: mpfcb->freelist = free;
309: mpfcb->frbcnt++;
310: }
311:
312: error_exit:
313: knl_UnlockOBJ(&mpfcb->lock);
314:
315: return ercd;
316: }
317:
318: #ifdef USE_FUNC_TK_REF_MPF
319: 320: 321:
322: SYSCALL ER tk_ref_mpf( ID mpfid, T_RMPF *pk_rmpf )
323: {
324: MPFCB *mpfcb;
325: ER ercd = E_OK;
326:
327: CHECK_MPFID(mpfid);
328: CHECK_DISPATCH();
329:
330: mpfcb = get_mpfcb(mpfid);
331:
332: knl_LockOBJ(&mpfcb->lock);
333: if ( mpfcb->mpfid == 0 ) {
334: ercd = E_NOEXS;
335: } else {
336: DISABLE_INTERRUPT;
337: pk_rmpf->wtsk = knl_wait_tskid(&mpfcb->wait_queue);
338: ENABLE_INTERRUPT;
339: pk_rmpf->exinf = mpfcb->exinf;
340: pk_rmpf->frbcnt = mpfcb->frbcnt;
341: }
342: knl_UnlockOBJ(&mpfcb->lock);
343:
344: return ercd;
345: }
346: #endif
347:
348:
349: 350: 351:
352: #if USE_DBGSPT
353:
354: #if USE_OBJECT_NAME
355: 356: 357:
358: EXPORT ER knl_fix_memorypool_getname(ID id, UB **name)
359: {
360: MPFCB *mpfcb;
361: ER ercd = E_OK;
362:
363: CHECK_MPFID(id);
364:
365: BEGIN_DISABLE_INTERRUPT;
366: mpfcb = get_mpfcb(id);
367: if ( mpfcb->mpfid == 0 ) {
368: ercd = E_NOEXS;
369: goto error_exit;
370: }
371: if ( (mpfcb->mpfatr & TA_DSNAME) == 0 ) {
372: ercd = E_OBJ;
373: goto error_exit;
374: }
375: *name = mpfcb->name;
376:
377: error_exit:
378: END_DISABLE_INTERRUPT;
379:
380: return ercd;
381: }
382: #endif
383:
384: #ifdef USE_FUNC_TD_LST_MPF
385: 386: 387:
388: SYSCALL INT td_lst_mpf( ID list[], INT nent )
389: {
390: MPFCB *mpfcb, *end;
391: INT n = 0;
392:
393: BEGIN_DISABLE_INTERRUPT;
394: end = knl_mpfcb_table + NUM_MPFID;
395: for ( mpfcb = knl_mpfcb_table; mpfcb < end; mpfcb++ ) {
396: if ( mpfcb->mpfid == 0 ) {
397: continue;
398: }
399:
400: if ( n++ < nent ) {
401: *list++ = ID_MPF(mpfcb - knl_mpfcb_table);
402: }
403: }
404: END_DISABLE_INTERRUPT;
405:
406: return n;
407: }
408: #endif
409:
410: #ifdef USE_FUNC_TD_REF_MPF
411: 412: 413:
414: SYSCALL ER td_ref_mpf( ID mpfid, TD_RMPF *pk_rmpf )
415: {
416: MPFCB *mpfcb;
417: ER ercd = E_OK;
418:
419: CHECK_MPFID(mpfid);
420:
421: mpfcb = get_mpfcb(mpfid);
422:
423: BEGIN_DISABLE_INTERRUPT;
424: if ( mpfcb->mpfid == 0 ) {
425: ercd = E_NOEXS;
426: } else if ( knl_isLockedOBJ(&mpfcb->lock) ) {
427: ercd = E_CTX;
428: } else {
429: pk_rmpf->wtsk = knl_wait_tskid(&mpfcb->wait_queue);
430: pk_rmpf->exinf = mpfcb->exinf;
431: pk_rmpf->frbcnt = mpfcb->frbcnt;
432: }
433: END_DISABLE_INTERRUPT;
434:
435: return ercd;
436: }
437: #endif
438:
439: #ifdef USE_FUNC_TD_MPF_QUE
440: 441: 442:
443: SYSCALL INT td_mpf_que( ID mpfid, ID list[], INT nent )
444: {
445: MPFCB *mpfcb;
446: QUEUE *q;
447: ER ercd = E_OK;
448:
449: CHECK_MPFID(mpfid);
450:
451: mpfcb = get_mpfcb(mpfid);
452:
453: BEGIN_DISABLE_INTERRUPT;
454: if ( mpfcb->mpfid == 0 ) {
455: ercd = E_NOEXS;
456: } else {
457: INT n = 0;
458: for ( q = mpfcb->wait_queue.next; q != &mpfcb->wait_queue; q = q->next ) {
459: if ( n++ < nent ) {
460: *list++ = ((TCB*)q)->tskid;
461: }
462: }
463: ercd = n;
464: }
465: END_DISABLE_INTERRUPT;
466:
467: return ercd;
468: }
469: #endif
470:
471: #endif
472: #endif