source: svn/newcon3bcm2_21bu/dst/dlib/src/osx/OSX_Task.c

Last change on this file was 76, checked in by megakiss, 10 years ago

1W 대기전력을 만족시키기 위하여 POWEROFF시 튜너를 Standby 상태로 함

  • Property svn:executable set to *
File size: 37.9 KB
Line 
1/**
2        @file
3                OSX_TAsk.c
4
5        @brief
6                Generic Purpose Task Template implementation.
7
8        Copyright 2006~2010 Digital STREAM Technology, Inc.
9        All Rights Reserved
10*/
11
12#include "DHL_OSAL.h"
13#include "DHL_DBG.h"
14
15#include "OSX_Task.h"
16
17//#include "DHL_DBG_Priv.h"
18//#include "DHL_OSAL_Config.h"
19
20//#include <stdio.h>
21////#include <string.h>
22
23//#include "mmac/types.h"
24//#include "mmac/rtos.h"
25
26
27
28DHL_MODULE("osx", 0);
29
30
31
32
33
34#if COMMENT
35____Config____(){}
36#endif
37
38
39#define USE_STRICT_CHECK 1
40        /*
41                ¾ö°ÝÇÑ Ã¼Å© ¼öÇà.
42                °³¹ß Áß¿¡¸¸ »ç¿ëÇÏ¸é µÉ °ÍÀ¸·Î º¸ÀÓ.
43        */
44
45
46
47#if COMMENT
48____Types____(){}
49#endif
50
51
52
53
54
55
56/*
57        ŽºÅ© À̸§ ÃÖ´ë ±æÀÌ.
58*/
59#define OSX_MAX_TASK_NAME 8
60
61
62/*
63        task command proc ¿¡¼­ »ç¿ëÇÒ argumentÀÇ ÃÖ´ë °¹¼ö.
64        ³Ê¹« ¸¹À¸¸é send message¿¡¼­ memcpy overhead ¹®Á¦°¡ ÀÖÀ½.
65        °æÇè»ó 4 Á¤µµ¸é ÃæºÐÇϸç,
66        ´õ ¸¹Àº µ¥ÀÌÅ͸¦ Àü´ÞÇϰíÀÚ ÇÑ´Ù¸é pointer¸¦ Àü´ÞÇϰí synchronous callÀ» »ç¿ëÇØ¾ß ÇÑ´Ù.
67*/
68#define OSX_MAX_CMD_PARAMS OSX_MAX_USER_PARAMS
69
70/*
71        ŽºÅ© msg queÀÇ µðÆúÆ® Å©±â.
72        task start ÇÒ ¶§ caller°¡ ÁöÁ¤ÇÑ´Ù. ÁöÁ¤ÇÏÁö ¾ÊÀ» °æ¿ì µðÆúÆ®·Î ÀÌ °ªÀÌ Àû¿ëµÈ´Ù.
73*/
74#define OSX_DEFAULT_MSG_QUE_SIZE 20
75
76
77
78/* osx task generation serial number type.
79        value '0' means task is not valid. (not initialized, not created, ...)
80*/
81typedef UINT8 T_OSX_TASK_SN; // allocated ÀÓÀ» ³ªÅ¸³»´Â Áö½Ã¾î.
82
83typedef UINT8 T_OSX_TAS_MAGIC; // validity¸¦ ³ªÅ¸³»´Â Áö½Ã¾î.
84/*
85
86*/
87#define OSX_TASK_MAGIC 0xA6
88
89
90/*
91        Command schedule Á¤º¸¸¦ º¸°üÇÏ´Â ±¸Á¶Ã¼.
92*/
93typedef struct 
94{
95        T_OSX_TASK_CMD idCmd;      // command id
96       
97        BOOLEAN used;      // TRUE if this entry is used (and active)
98       
99        UINT32 period;     // interval (if periodic execution), or delay (if delayed execution)
100                           // unit is in ms
101                           
102        UINT32 start;      // time of schedule registration.
103                           // if this cmd executed periodically, 'start' is reset to NOW at every execution.
104
105        UINT16 flags;      // flags
106
107        F_OSX_TASK_PROC fn;  // command execution function
108        UINT32  params[OSX_MAX_CMD_PARAMS];   // command arguements
109       
110} S_OSX_CMD_SCHED;
111
112
113struct S_OSX_TASK_t; // forward declare
114
115typedef struct
116{
117        struct S_OSX_TASK_t *xt;  // back link to parent osx task info
118       
119        //-------- OS handles --------
120        DHL_OS_TASK_ID tid;
121                // OSAL task id (handle)
122
123        DHL_OS_MSGQ_ID msgQue;   // message queue of this task
124
125        DHL_OS_SEMA_ID semAck;   // binary semaphore for returning ACK.
126        DHL_OS_SEMA_ID mutexAck; // mutex for guard semAck
127
128        //-------- some params --------
129        int nCmdParam;
130                // number of command parameter. copied from xt->setting->num_cmd_param.
131                // OSX_MAX_CMD_PARAMS º¸´Ù Ŭ ¼ö ¾ø´Ù.
132
133} S_OSX_TASK_PUBLIC;
134
135
136typedef struct S_OSX_TASK_t
137{
138        T_OSX_TAS_MAGIC magic;
139                // validity indicator
140                // OSX_TASK_MAGIC °ªÀ» °¡Áö¸é ÀÌ ±¸Á¶Ã¼ Á¤º¸´Â allocated µÇ¾úÀ¸¸ç valid ÇÔÀ» ÀǹÌ.
141
142        T_OSX_TASK_SN serial; 
143                // ÃʱâÈ­ ÀϷùøÈ£. 0À̸é ÀÌ task Á¤º¸´Â ¹Ì»ç¿ë(not-allocated)À̶ó´Â ÀǹÌÀÓ.
144                // ÀÌ serial ¹øÈ£´Â task°¡ »ý¼ºµÉ ¶§ °ªÀÌ ºÎ¿©µÇ°í, shutdownµÇ¸é 0ÀÌ µÈ´Ù.
145                // ÀÌ serial ¹øÈ£´Â ÇöÀç µ¿ÀÛ ÁßÀÎ task µé°ú Áߺ¹µÇÁö ¾Ê´Â´Ù.
146
147        /*
148                ÇÒ´ç ¼ø¼­: serial = s#; magic = MAGIC_VALUE;
149                        see p_alloc_osx_task(), OSX_TaskStart()
150                       
151                ÇØÁ¦ ¼ø¼­: magic = 0; serial = 0;
152                        see p_shutdown_task(), p_free_osx_task()
153        */
154
155        UINT8  index;  // task list ¿¡¼­ÀÇ ¼ø¼­ index. array ¶ó¸é array indexÀÓ.
156       
157        S_OSX_TASK_PUBLIC pti; // public task information.
158                // ÀÌ Á¤º¸µéÀº ÀÓÀÇ task¿¡¼­ ÇÊ¿ä·Î ÇÏ´Â °ÍµéÀÌ´Ù.
159                // ¿©±â¿¡ Á¢±ÙÇÏ·Á¸é mutex°¡ ÇÊ¿äÇÏ´Ù.
160       
161        //-------- state --------
162
163        /* task À̸§ */
164        char name[OSX_MAX_TASK_NAME+1];
165
166        /* task ÃʱâÈ­ ¼³Á¤ ÆÄ¶ó¹ÌÅÍ */
167        S_OSX_TASK_INIT_SETTING setting;
168                // user settings parameter for task init
169
170        int nMaxQueSize;
171                // copied from setting->msg_que_size.
172
173        T_OSX_TASK_CMD curServicedCmdId;
174                // ÇöÀç task¿¡¼­ ¼­ºñ½º ÁßÀÎ cmd id.
175                // task°¡ idle »óÅÂÀÏ °æ¿ì¿¡´Â 0ÀÌ µÈ´Ù.
176
177
178        //struct OSX_TASK_t *next;
179                // for management.. next task info..
180
181        //-------- ¿¹¾à ¸í·É Áö¿ø ÄÚµå --------
182
183        int  nMaxSlot;
184                // maximum number of element of sclist. (size of sclist)
185       
186        int  nScheduledCmd;
187                // ÇöÀç µî·ÏµÈ ¿¹¾à ¸í·É °¹¼ö.
188                // nMaxSlot º¸´Ù Ŭ ¼ö ¾ø´Ù.
189               
190        int  maxActiveIndex;
191                // ¿¹¾à ¸í·É ¸®½ºÆ®¿¡¼­ ÇöÀç active ÇÑ cmdÀÇ ¹è¿­ À妽º °ªÀÇ ÃÖ´ë°ª.
192                // list Áß°£¿¡ ÀÖ´Â cmd ¸¦ stop ½ÃÄÑ ¾ø¾Ö¸é ¹è¿­ °¡¿îµ¥°¡ ºó »óŰ¡ µÇ´Âµ¥,
193                // ÀÌ °æ¿ì nActiveTimer¿Í ¹«°üÇÑ °ªÀÌ µÉ ¼ö ÀÖ´Ù.
194                // main task¿¡¼­ ÀÌ °ªÀ» ¾Ë°í ÀÖÀ¸¸é loop ¿À¹öÇìµå¸¦ ¾à°£ ÁÙÀÏ ¼ö ÀÖ´Ù.
195       
196        S_OSX_CMD_SCHED *sclist; 
197                // ¿¹¾à ¸í·É (scheduled command) ¸®½ºÆ® Á¤º¸.
198
199} S_OSX_TASK;
200
201/*
202        internal task command id.
203
204        S_OSX_TASK_CMD::idCmd ¿¡¼­ »ç¿ëÀÚ command ¿Í °°ÀÌ »ç¿ëµÈ´Ù.
205        ¿©±âÀÇ °ªµéÀº »ç¿ëÀÚ°¡ user command id·Î »ç¿ëÇÒ ¼ö ¾ø´Ù.
206        »ç¿ëÇÏ·Á°í Çϸé API ¾È¿¡¼­ ¿¡·¯°¡ ¹ß»ýÇÑ´Ù.
207*/
208typedef enum //E_OSX_TASK_CMD_t
209{
210        eTASK_CMD_BEGIN = OSX_CMD_RESERVED,  // this is just marker.
211
212        eTASK_CMD_DELETE,
213                // Timer entry Çϳª¸¦ »èÁ¦ÇÑ´Ù.
214                // »èÁ¦(Ãë¼Ò)ÇÒ command id´Â params[0]À» ÅëÇØ Àü´ÞÇÑ´Ù.
215
216        eTASK_CMD_DELETE_ALL,
217                // ¸ðµç ¿¹¾à cmd entry »èÁ¦.
218                //
219       
220        eTASK_CMD_SHOW,
221
222        eTASK_CMD_QUERY,
223
224        eTASK_CMD_SYNC,
225                // ƯÁ¤ ¸í·ÉÀÌ wait ¸ðµå(blocking mode, synchronous mode)·Î µ¿ÀÛÇØ¾ßÇÑ ÇÏ´Â °æ¿ì
226                // ÀÌ command¸¦ »ç¿ëÇϸé task ½ÇÇà°ú µ¿±âÈ­°¡ µÇ¾î
227                // wait ¸ðµåÀÇ È¿°ú°¡ ³­´Ù.
228                // app ¿¡¼­ Á÷Á¢ semaphore, mutex µîÀ» °ü¸®ÇÏ´Â °ÍÀÌ ¹ø°Å·Î¿ï °æ¿ì
229                // °£´ÜÇÏ°Ô ÀÌ ¸í·ÉÀ» Ȱ¿ëÇÏ¸é µÈ´Ù.
230
231        eTASK_CMD_SHUTDOWN,
232       
233} E_OSX_TASK_CMD;
234
235
236/*
237        task ¸í·É ¸Þ½ÃÁö ±¸Á¶Ã¼.
238        ½ÇÁ¦·Î OSÀÇ SendMessage¸¦ ÅëÇØ Àü´ÞµÇ´Â ¸Þ½ÃÁöÀÌ´Ù.
239        ÀÌ ±¸Á¶Ã¼ Å©±â°¡ Ä¿Áú ¼ö·Ï SendMessage ³»ÀÇ ºÎÇϰ¡ ºñ·ÊÇÏ¿© Ä¿Áø´Ù.
240        µû¶ó¼­ ºÒÇÊ¿äÇÑ Çʵå´Â Ãß°¡ÇÏÁö ¾Êµµ·Ï ½Å°æÀ» ½á¾ß ÇÑ´Ù.
241*/
242typedef struct
243{
244        T_OSX_TASK_CMD idCmd;
245                // Command ID
246                // this command ID should be unique in S_OSX_TASK.
247                // ¿©±â¿¡ »ç¿ëµÇ´Â °ªµéÀº ÀÏ¹Ý ¼ýÀÚ °ªÀ̰ųª E_OSX_TASK_CMD ³»ºÎ ¸í·ÉÀÌ »ç¿ëµÈ´Ù.
248
249        T_OSX_TASK_SN snTask;
250                // task serial number
251       
252        UINT16 flags;
253                // °¢Á¾ flag.
254
255        UINT32 nDelayMs;
256                // timer expire ÁÖ±â.
257                // eTASK_CMD_DELETE ÀÎ °æ¿ì pResult ¿ªÇÒÀ» ÇÑ´Ù.
258       
259        F_OSX_TASK_PROC func;
260                // ÀÌ command id¿¡ ÀÇÇØ ½ÇÇàµÉ ¸í·É ÇÔ¼ö.
261       
262        UINT32 params[OSX_MAX_CMD_PARAMS];  // cmd parameter (func argument)
263                // ÀÌ params´Â °¡º¯ ±æÀÌ ¹è¿­ÀÌ´Ù.
264                // task ÃʱâÈ­ °úÁ¤¿¡¼­ ƯÁ¤ size(°¹¼ö)·Î °íÁ¤µÈ´Ù.
265                // µû¶ó¼­ params Çʵ尡 ÀÌ S_OSX_TASK_CMD ±¸Á¶Ã¼ÀÇ ¸Ç µÚ¿¡ À§Ä¡ÇØ¾ß ÇÑ´Ù.
266
267} S_OSX_TASK_CMD;
268
269
270/**
271        S_OSX_TASK_CMD ÀÇ Å©±â´Â °¡º¯ÀÌ´Ù. Á¤È®ÇÑ size´Â nCmdParam °ª¿¡ µû¶ó ´Þ¶óÁø´Ù.
272
273        SendMessage ÇÒ ¶§ ±×³É ÃÖ´ë Áö¿ø °¹¼öÀÎ OSX_MAX_CMD_PARAMS ¸¦ »ç¿ëÇÏÁö ¾Ê´Â ÀÌÀ¯´Â
274        ºÒÇÊ¿äÇÑ memcopy overhead¸¦ ÁÙÀ̱â À§ÇÔÀÌ´Ù.
275*/
276#define OSX_COMMAND_SIZE(num_param) (\
277        sizeof(S_OSX_TASK_CMD) \
278        - sizeof(UINT32)*OSX_MAX_CMD_PARAMS \
279        + sizeof(UINT32)*(num_param) \
280        )       
281
282
283#ifndef min
284        #define min(a,b) ((a)<(b)?(a):(b))
285#endif
286
287
288/*
289        H_OSX_TASK ÇÚµé ±¸¼º.
290                task listÀÇ index¿Í serial number·Î ±¸¼ºÇÑ´Ù.
291                ÃÖ´ë task °¹¼ö´Â 256 À¸·Î ÇÑÁ¤. 8 ºñÆ®¸é µÊ.
292                serial ¹øÈ£´Â 0~0xFF ¸é ÃæºÐ. 8ºñÆ®¸é µÊ.
293        MSB 16 bits: osx task list index | 0x100
294        LSB 16 bits: osx task generation serial
295*/
296#define MAKE_OSX_HANDLE(index, serial) (0x10000 | (((index)&0xff)<<8UL) | ((serial)&0xff))
297#define INDEX_FROM_HANDLE(handle)    ( ((handle)>>8) & 0xff )
298#define SERIAL_FROM_HANDLE(handle) ( (handle)&0xff )
299
300
301
302#if COMMENT
303____Variables____(){}
304#endif
305
306/*
307        »ý¼ºµÈ ¸ðµç osx task ¸®½ºÆ®.
308S_OSX_TASK *s_osx_task_list;
309*/
310
311/*      osx task list Á¤º¸.
312*/
313S_OSX_TASK  s_osx_tasks[OSX_MAX_TASK];
314
315/*      task serial ¹øÈ£ ¹ß±Þ ¿ë º¯¼ö.
316        ÀÌ º¯¼öÀÇ °ªÀº °¡Àå ¸¶Áö¸·¿¡ ¹ß±ÞÇÑ ¹øÈ£ÀÓ.
317        serial 0 Àº ¹ß±ÞÇÏ¸é ¾ÈµÈ´Ù. '¹Ì»ç¿ë'ÀÇ Àǹ̷Π»ç¿ëµÇ¹Ç·Î.
318*/
319T_OSX_TASK_SN s_osx_serial;
320
321
322/*      osx task Á¤º¸¿¡ ´ëÇÑ mutex.
323
324        »ç¿ëµÇ´Â °÷:
325        1. ÃÖÃÊ¿¡ task start ÇÏ´Â ½ÃÁ¡¿¡¼­¸¸ »ç¿ëµÇ¸ç, (called in arbitrary task)
326                ±× ÀÌÈÄ¿¡´Â »ý¼ºµÈ task ¿¡¼­¸¸ »ç¿ëÇÏ´Â °ÍÀ¸·Î ÇÑ´Ù.
327        2. ÀÓÀÇ task¿¡¼­ task public Á¤º¸¸¦ °¡Á®¿Ã ¶§ »ç¿ëµÈ´Ù.
328*/
329DHL_OS_SEMA_ID s_osx_mutex;
330
331
332
333S_OSX_TASK *s_osx_traced;
334        // trace ÇϰíÀÚ ÇÏ´Â task handle.
335        // Àüü task ¸®½ºÆ®¸¦ È®ÀÎÇÑ ÈÄ¿¡ ÇÚµé °ªÀ» ÁöÁ¤ÇØ ÁÖ¸é µÈ´Ù.
336
337
338
339
340/*
341        ÀÌ ÇÔ¼ö´Â ÀÓÀÇ task¿¡¼­ È£ÃâµÈ´Ù.
342*/
343static S_OSX_TASK *p_alloc_osx_task(void)
344{
345        int i;
346        S_OSX_TASK *xt = NULL;
347       
348        // ¸Ç ¸ÕÀú serialÀ» µî·ÏÇÏ´Â task°¡ owner°¡ µÈ´Ù.
349        DHL_OS_TakeSemaphore(s_osx_mutex, DHL_TIMEOUT_FOREVER);
350        for (i=0; s_osx_tasks[i].serial==0 && i<OSX_MAX_TASK; i++) {
351                // »õ·Î¿î ÀÏ·Ã ¹øÈ£ Áغñ.
352                if (++s_osx_serial == 0)
353                        s_osx_serial = 1;
354                memset(&s_osx_tasks[i], 0, sizeof(S_OSX_TASK));         
355                // ¹øÈ£ ¹ß±Þ ¹× osx task ÇÒ´ç.
356                s_osx_tasks[i].serial = s_osx_serial;
357                s_osx_tasks[i].index = i;
358                xt = &s_osx_tasks[i];
359                break;
360        }
361        DHL_OS_GiveSemaphore(s_osx_mutex);
362
363        return xt;
364}
365
366static void p_free_osx_task(S_OSX_TASK *xt)
367{
368        DHL_OS_TakeSemaphore(s_osx_mutex, DHL_TIMEOUT_FOREVER);
369        xt->magic = 0;
370        xt->serial = 0;
371        DHL_OS_GiveSemaphore(s_osx_mutex);
372}
373
374static void p_validate_osx_task(S_OSX_TASK *xt)
375{
376        DHL_OS_TakeSemaphore(s_osx_mutex, DHL_TIMEOUT_FOREVER);
377        xt->magic = OSX_TASK_MAGIC;
378        DHL_OS_GiveSemaphore(s_osx_mutex);
379}
380static void p_invalidate_osx_task(S_OSX_TASK *xt)
381{
382        DHL_OS_TakeSemaphore(s_osx_mutex, DHL_TIMEOUT_FOREVER);
383        xt->magic = 0;
384        DHL_OS_GiveSemaphore(s_osx_mutex);
385}
386
387#if COMMENT
388______Func____(){}
389#endif
390
391static BOOL s_module_init;
392static void osx_module_init(void);
393
394static int p_list_all_osx_task(H_OSX_TASK *list)
395{
396        int i;
397        int n_task = 0;
398        DHL_OS_TakeSemaphore(s_osx_mutex, DHL_TIMEOUT_FOREVER);
399        for (i=0; i<OSX_MAX_TASK; i++) {
400                if (s_osx_tasks[i].magic == OSX_TASK_MAGIC)
401                        list[n_task++] = MAKE_OSX_HANDLE(i, s_osx_tasks[i].serial);
402        }
403        DHL_OS_GiveSemaphore(s_osx_mutex);
404        return n_task;
405}
406
407
408/*      osx task ÇÚµéÀÌ À¯È¿ÇÑ ÇÚµéÀÎÁö üũ.
409        ÀÌ ÇÔ¼ö´Â ÀÏ¹Ý ÀÓÀÇ task¿¡¼­µµ È£ÃâµÈ´Ù.
410*/
411static S_OSX_TASK_PUBLIC *p_get_osx_task(H_OSX_TASK handle, S_OSX_TASK_PUBLIC *pti)
412{
413        S_OSX_TASK *xt;
414        S_OSX_TASK_PUBLIC *ret = NULL;
415        UINT16 index;
416
417        // ¸Ç ¸ÕÀú serialÀ» µî·ÏÇÏ´Â task°¡ owner°¡ µÈ´Ù.
418        DHL_OS_TakeSemaphore(s_osx_mutex, DHL_TIMEOUT_FOREVER);
419
420        index = INDEX_FROM_HANDLE(handle);
421        if (index >= OSX_MAX_TASK) {
422                dprint(0, "!! invalid osx task handle 0x%x\n", handle);
423                goto end;
424        }
425        xt = &s_osx_tasks[index];
426        if (xt->serial != SERIAL_FROM_HANDLE(handle) ||
427                xt->magic != OSX_TASK_MAGIC) {
428                dprint(0, "!! wrong osx task info: handle %x, serial %x magic %x\n", 
429                                handle, xt->serial, xt->magic);
430                goto end;
431        }
432        if (xt->pti.tid == 0) {
433                dprint(0, "!! task not initialized!\n");
434                goto end;
435        }
436        *pti = xt->pti;
437        ret = pti; // return pointer of caller's pti copy, NOT &xt->pti.
438
439end:
440        DHL_OS_GiveSemaphore(s_osx_mutex);
441        return ret;
442}
443
444
445#if USE_STRICT_CHECK
446static void p_assert_in_task(S_OSX_TASK *xt, const char *fn)
447{
448        DHL_OS_TASK_ID tid = DHL_OS_GetTaskID();
449        if (!xt || tid != xt->pti.tid) {
450                dprint(0, "!! %s should be called inside task! xt %x, tid %x != xt's %x\n", 
451                                fn, xt, tid, xt?xt->pti.tid:0);
452                DHL_ASSERT(FALSE, "");
453        }
454}
455#endif
456
457
458
459
460#if COMMENT
461______TaskMethod____(){}
462#endif
463
464/*
465        add one scheduled command
466*/
467static DHL_RESULT p_add_scheduled_cmd(S_OSX_TASK *xt, S_OSX_TASK_CMD *cmd)
468{
469        int i;
470        int iSelected, iEmpty;
471
472#if USE_STRICT_CHECK
473        p_assert_in_task(xt, __func__);
474#endif
475
476        if (cmd->nDelayMs == 0) { // ¿¡·¯.
477                dprint(0, "!! task %s: schedule cmd with zero delay\n", xt->name);
478                return DHL_FAIL_INVALID_PARAM;
479        }
480        if ((cmd->flags & eTASK_FLAG_Repeat) && (cmd->nDelayMs <= 2)) {
481                dprint(0, "!! task %s: too short period %d\n", xt->name, cmd->nDelayMs);
482                // ÀÏ´Ü ±×´ë·Î ÁøÇà.
483        }
484
485        // id¸¦ °Ë»öÇϸ鼭, µ¿½Ã¿¡ empty slotµµ ã´Â´Ù.
486        // ÇØ´ç ID°¡ ÀÌ¹Ì »ç¿ëÁßÀ̶ó¸é °»½Å¸ðµå..
487       
488        iSelected = -1;
489        iEmpty = -1;
490       
491        for (i=0; i<xt->nMaxSlot; i++)
492        {
493                if (xt->sclist[i].used && xt->sclist[i].idCmd == cmd->idCmd) {
494                        // ÀÌ¹Ì »ç¿ëÁßÀÌ´Ù..
495                        // »õ·Î¿î parameter·Î updateÇϰí ÇÔ¼ö Á¾·á..
496                        if (s_osx_traced == xt)
497                        dprint(0, "!! cmd (id 0x%x) already scheduled. updated..\n", cmd->idCmd);
498                        iSelected = i;
499                        break;
500                }
501                else if (xt->sclist[i].used == 0) {
502                        // ºñ¾îÀÖ´Â slotÀ» ã´Â´Ù..
503                        if (iEmpty < 0) iEmpty = i;
504                }
505        }
506       
507        if (iSelected < 0) // µ¿ÀÏÇÑ
508                iSelected = iEmpty;
509       
510        if (iSelected >= 0) 
511        {
512                S_OSX_CMD_SCHED *psc = &xt->sclist[iSelected];
513                if (psc->used == FALSE) {
514                        xt->nScheduledCmd++;
515                }
516               
517                psc->idCmd = cmd->idCmd;
518                psc->period = cmd->nDelayMs;
519                psc->fn = cmd->func;
520                for (i=0; i<xt->pti.nCmdParam; i++)
521                        psc->params[i] = cmd->params[i];
522                for (; i<OSX_MAX_CMD_PARAMS; i++)  // fill unused remaining params with 0.
523                        psc->params[i] = 0;
524                psc->flags = cmd->flags;
525               
526                psc->start = DHL_OS_GetMsCount();
527                psc->used = TRUE;
528               
529                // maxActiveIndex¸¦ ¾Ë¾ÆµÎ¸é TimerTask¿¡¼­ loop¸¦ µ¹¶§ µµ¿òÀÌ µÈ´Ù.
530                if (xt->maxActiveIndex < iSelected)
531                        xt->maxActiveIndex = iSelected;
532                       
533                if (s_osx_traced == xt)
534                dprint(0, "   add: cmd[%d] id 0x%x, total %d active\n", iSelected, cmd->idCmd, xt->nScheduledCmd);
535        }
536        else {
537                //if (s_osx_traced == xt)
538                dprint(0, "!! task %s: no more cmd slot for cmd 0x%x\n", xt->name, cmd->idCmd);
539                // it may be available some time later because oneshot timer will die..
540        }
541       
542        return iSelected >= 0 ? DHL_OK : DHL_FAIL_NOT_AVAILABLE;
543}
544
545/*
546        delete one timer entry.
547        this function should be called in timer task.
548*/
549static DHL_RESULT p_del_scheduled_cmd(S_OSX_TASK *xt, T_OSX_TASK_CMD idCmd)
550{
551        int i;
552        DHL_RESULT dhr = DHL_FAIL_NOT_FOUND;
553        int maxActiveIndex = -1;
554       
555#if USE_STRICT_CHECK
556        p_assert_in_task(xt, __func__);
557#endif
558
559        if (idCmd == (T_OSX_TASK_CMD)-1) { // delete all..
560                if (s_osx_traced == xt)
561                        dprint(0, "delete all sch.cmd\n");
562
563                memset(&xt->sclist, 0, xt->nMaxSlot*sizeof(S_OSX_CMD_SCHED));
564                xt->nScheduledCmd = 0;
565                xt->maxActiveIndex = -1;
566                dhr = DHL_OK;
567        }
568
569        for (i=0;i<=xt->maxActiveIndex;i++)
570        {
571                if (xt->sclist[i].used == FALSE) 
572                        continue;
573
574                if (xt->sclist[i].idCmd == idCmd) { // delete ´ë»ó command.
575                        memset(&xt->sclist[i], 0, sizeof(S_OSX_CMD_SCHED));
576                        xt->nScheduledCmd--;
577
578                        if (s_osx_traced == xt)
579                                dprint(0, "delcmd: index: %d, ID: %d\n", i, idCmd);
580                        dhr = DHL_OK;
581                }
582                else {
583                        maxActiveIndex = i;
584                }
585        }
586        xt->maxActiveIndex = maxActiveIndex;
587        return dhr;
588}
589
590/*
591        show timer sclist
592*/
593static void p_show_scheduled_cmd(S_OSX_TASK *xt, S_OSX_TASK_CMD *cmd)
594{
595        DHL_RESULT dhlResult;
596        int i, k;
597        char buf[80];
598       
599#if USE_STRICT_CHECK
600        p_assert_in_task(xt, __func__);
601#endif
602
603        DHL_OS_Printf("----- Task %x, handle %x -----\n", xt, MAKE_OSX_HANDLE(xt->index, xt->serial));
604       
605        DHL_OS_Printf(" '%s', prio %d, max slot %d\n", 
606                        xt->name, xt->setting.priority, xt->nMaxSlot);
607       
608        for (i=0; i<=xt->maxActiveIndex; i++) {
609                char *fname = NULL;
610                if (!xt->sclist[i].used) continue;
611                // dhl_dbg_find_sym_by_addr((UINT32)xt->sclist[i].fn, &fname);
612                for (buf[0]=0, k=0; k<min(4, xt->pti.nCmdParam); k++)
613                        sprintf(buf+strlen(buf), "%x ", xt->sclist[i].params[k]); 
614                DHL_OS_Printf(" (%02d) ID %d, fn %x(%s) arg (%s), %d ms, f%x %s%s\n", i, 
615                        xt->sclist[i].idCmd,
616                        xt->sclist[i].fn, fname ? fname : "?",
617                        buf,
618                        xt->sclist[i].period,
619                        //xt->sclist[i].period,
620                        xt->sclist[i].flags,
621                        xt->sclist[i].flags & eTASK_FLAG_Delayed ? "delayed " : "",
622                        xt->sclist[i].flags & eTASK_FLAG_Repeat ? "repeat " : "");
623        }
624        DHL_OS_Printf("\n");
625}
626
627
628/*
629        »ç¿ëÀÚ ¸í·ÉÀ» È£ÃâÇÑ´Ù.
630        ¹Ù·Î ¼öÇà ¸í·ÉÀÏ ¼öµµ ÀÖ°í, ¿¹¾à ¸í·ÉÀÏ ¼öµµ ÀÖÀ½.
631*/
632void p_callback_user_func(S_OSX_TASK *xt, T_OSX_TASK_CMD idCmd, UINT16 flags, 
633                        F_OSX_TASK_PROC pFn, UINT32 *params)
634{
635        // task callbackÀÌ ºÒ¸®´Â µ¿¾È¿¡´Â ¾î¶² task id°¡ service ÁßÀÎÁö ±â·ÏÀ» ³²°ÜµÎÀÚ.
636        xt->curServicedCmdId = idCmd;
637       
638        if (s_osx_traced == xt)
639        dprint(0, "\n---------- ExecBegin: %x, cmd 0x%x, fn 0x%x, param[0] 0x%x \n", 
640                        xt, idCmd, pFn, params[0]);
641
642        if (xt->pti.nCmdParam <= 2)
643                pFn(idCmd, params[0], params[1]);
644        else if (xt->pti.nCmdParam <= 4)
645                pFn(idCmd, params[0], params[1], params[2], params[3]);
646        else
647                // OSX_MAX_USER_PARAMS ¸¸Å­ Áö¿øÇØ¾ß ÇÑ´Ù. À̰ÍÀº programmatic ÇÏ°Ô ±¸Çö ¾î·Á¿ò.
648                pFn(idCmd, params[0], params[1], params[2], params[3],
649                                params[4], params[5], params[6], params[7]);
650
651        if (s_osx_traced == xt)
652        dprint(0,   "---------- ExecEnd: %x, ID %d \n\n", xt, idCmd);
653
654        xt->curServicedCmdId = 0;
655        // idCmd 0Àº ¿©±â¼­ ó·³ Ưº°ÇÑ Àǹ̷Π»ç¿ëÇϹǷÎ, ÀÏ¹Ý command ID·Î´Â reserve ÇØ¾ß ÇÑ´Ù.
656
657}
658
659
660void p_shutdown_task(S_OSX_TASK *xt)
661{
662#if USE_STRICT_CHECK
663        p_assert_in_task(xt, __func__);
664#endif
665
666        dprint(2, "task stop requested..\n");
667
668        // ´õ ÀÌ»ó »õ·Î¿î task ¸í·ÉÀÌ Àü´ÞµÇÁö ¾Êµµ·Ï ¼± Á¶Ä¡. invalidate.
669        //xt->magic = 0;
670        p_validate_osx_task(xt);
671       
672        DHL_OS_DeleteSemaphore(xt->pti.semAck);
673        xt->pti.semAck = 0;
674
675        DHL_OS_DeleteSemaphore(xt->pti.mutexAck);
676        xt->pti.mutexAck = 0;
677
678        DHL_OS_DeleteMessageQueue(xt->pti.msgQue);
679        xt->pti.msgQue = 0;
680       
681        dprint(2, "task about to shutdown..\n");
682        xt->pti.tid = 0;
683
684        // osx task ±¸Á¶Ã¼¸¦ empty ÇÏ¿© ´Ù¸¥ task¿¡ ÇÒ´çµÉ ¼ö ÀÖµµ·Ï Á¶Ä¡.
685        p_free_osx_task(xt);
686       
687        DHL_OS_SelfDeleteTask();
688}
689
690
691#if COMMENT
692____Task____() {}
693#endif
694
695/*
696        task main.
697       
698*/
699
700static void p_task_main(S_OSX_TASK *xt)
701{       
702        int i;
703        DHL_RESULT result;
704        S_OSX_TASK_CMD cmd;
705       
706        int nMinRemainingMs; // °¡Àå ¸ÕÀú ½ÇÇà µÉ ¿¹¾à ¸í·É¾î ±îÁöÀÇ ½Ã°£.
707        UINT32 uNow;
708
709        while(xt->pti.tid == 0) // wait until creator returns DHL_OS_CreateTask api.
710                DHL_OS_Delay(10);
711
712        dprint(1, "osx task start, xt %x, s# %x, name '%s', handle %x\n", 
713                        xt, xt->serial, xt->name, MAKE_OSX_HANDLE(xt->index, xt->serial));
714       
715        while (TRUE)
716        {
717                nMinRemainingMs = 0x7fffffff;  // signed INT32 valueÀÇ ÃÖ´ë°ª..
718
719                //--------- timer expiration timeout üũ ------------
720                // ÇöÀç °¡Àå °¡±î¿î ½Ã°£ ³»¿¡ expire µÉ timer¸¦ ã´Â´Ù..
721               
722                uNow = DHL_OS_GetMsCount();
723                for (i=0; i<=xt->maxActiveIndex; i++)
724                {
725                        int nRemainMs;
726                        if (xt->sclist[i].used == 0) continue;
727                        nRemainMs = (int) (xt->sclist[i].start + xt->sclist[i].period - uNow);
728                        // ÀÌ¹Ì expire µÈ timer¶ó¸é remainÀº negative °ªÀ» °¡Áú °ÍÀÓ..
729                       
730                        if (nMinRemainingMs > nRemainMs) {
731                                nMinRemainingMs = nRemainMs;
732                        }
733                }
734
735                //--------- wait message with/without timeout ------------
736
737                /*
738                        nMinRemainingMs°¡ 0À̶ó¸é ¹Ù·Î ½ÇÇàÇØ¾ß ÇÒ ¿¹¾à ¸í·ÉÀÌ ÀÖ´Ù´Â ÀǹÌÀÌ´Ù.
739                        ÀÌ °ªÀº <0 ÀÏ ¼öµµ ÀÖ´Ù. (ÀÌ¹Ì ½ÇÇàÇØ¾ß ÇÒ ½Ã°£ÀÌ °æ°úÇÑ °æ¿ì)
740                       
741                        ¼³·É ÀÌ¹Ì expire µÈ entry°¡ ÀÖ´Ù°í ÇÏ´õ¶óµµ
742                        taskÀÇ ½ÇÇà ºÎÇϰ¡ ¸¹¾Æ¼­ command¸¦ ¾Æ¿¹ ¸ø¹Þ´Â »óȲÀÌ µÇÁö ¾Êµµ·Ï,
743                        msgque ´Â ¹Ýµå½Ã ÇѹøÀº üũ¸¦ ¼öÇàÇÏ°í ³ª¼­ ¿¹¾à ¸í·É ó¸®ÇØ ÁØ´Ù.
744
745                        ÀÌ °æ¿ì ReceiveMessage´Â No-wait ¸ðµå·Î ½ÇÇàµÈ´Ù.
746                */
747                // it can be negative. so adjust required.
748                if (nMinRemainingMs < 0) nMinRemainingMs = 0;
749
750                // ¾ÆÁ÷ ³²Àº ½Ã°£ÀÌ ¸¹±â ¶§¹®¿¡ SleepÀ» ÇÑ´Ù.
751                if (nMinRemainingMs < 0x7fffffff) {
752                        if (s_osx_traced == xt)
753                                dprint(2, "task enter sleep for %d ms..\n", nMinRemainingMs);
754                       
755                        result = DHL_OS_ReceiveMessage(xt->pti.msgQue, &cmd, nMinRemainingMs);
756                }
757                else {
758                        // ó¸®ÇØ¾ß ÇÒ ³²Àº timer°¡ ¾ø´Ù¸é active µÉ¶§±îÁö ¹«ÇÑÁ¤ ±â´Ù¸®±â¸¸ ÇÏ¸é µÈ´Ù.
759                        //
760                        if (s_osx_traced == xt)
761                                dprint(2, "task wait msg..\n");
762                        result = DHL_OS_ReceiveMessage(xt->pti.msgQue, &cmd, DHL_TIMEOUT_FOREVER);
763                }
764
765                //--------- process message if we got new one ------------
766
767                if (result == DHL_OK) // we got command
768                {
769                        // check task serial number.
770                        if (cmd.snTask != xt->serial) {
771                                dprint(0, "!! cmd %x (sn %x) is not for our task (sn %x)\n", 
772                                        cmd.idCmd, cmd.snTask, xt->serial);
773                                // shutdown µÇ±â Àü¿¡ send µÈ command°¡ ÀÌÁ¦¼­¾ß 󸮵Ǵ °ÍÀÏ ¼ö ÀÖÀ½.
774                                // ÀÌ ¸í·ÉÀº ±×³É Á¶¿ëÈ÷ ignore ÇÑ´Ù.
775                        }
776                       
777                        // add / delete / query / shutdown
778                       
779                        else if (cmd.idCmd < eTASK_CMD_BEGIN) { // ³»ºÎ ¸í·ÉÀÌ ¾Æ´Ï¸é ½ÇÇà ¸í·ÉÀÓ.
780                                // delay°¡ ¾Æ´Ï¶ó¸é ¹Ù·Î ½ÇÇà.
781                                if (!(cmd.flags & eTASK_FLAG_Delayed)) {
782                                        // ÇØ´ç case:
783                                        //   eTASK_FLAG_Normal, eTASK_FLAG_NowAndRepeat
784                                        p_callback_user_func(xt, cmd.idCmd, cmd.flags, cmd.func, cmd.params);
785                                }
786                                // delay ¶Ç´Â repeat ¿É¼ÇÀÎ °æ¿ì list¿¡ µî·ÏÇØ¾ß ÇÑ´Ù.
787                                // ´Ü ÀÌ °æ¿ì¿¡´Â nDelayMs°¡ 0ÀÌ ¾Æ´Ï¾î¾ß ÇÔ.
788                                if ((cmd.flags & eTASK_FLAG_Repeat) || (cmd.flags & eTASK_FLAG_Delayed)) {
789                                        // ÇØ´ç case:
790                                        //   eTASK_FLAG_Delayed, eTASK_FLAG_WaitAndRepeat, eTASK_FLAG_NowAndRepeat
791                                        result = p_add_scheduled_cmd(xt, &cmd);
792                                        if (s_osx_traced == xt)
793                                                OSX_TaskShow(MAKE_OSX_HANDLE(xt->index, xt->serial));
794                                }
795                        }
796                        else if (cmd.idCmd == eTASK_CMD_DELETE) {
797                                // delete ÀÎ °æ¿ì´Â »èÁ¦ÇÒ cmd id°¡ params[0]À» ÅëÇØ Àü´Þ µÈ´Ù.
798                                result = p_del_scheduled_cmd(xt, (T_OSX_TASK_CMD)cmd.params[0]);
799                        }
800                        else if (cmd.idCmd == eTASK_CMD_DELETE_ALL) {
801                                result = p_del_scheduled_cmd(xt, (T_OSX_TASK_CMD)eTASK_CMD_DELETE_ALL);
802                        }
803                        else if (cmd.idCmd == eTASK_CMD_SYNC) {
804                                ; // Ưº°È÷ ó¸®ÇÒ °Í ¾øÀ½. ±×³É ¾Æ·¡¿¡¼­ ack¸¸ ÁÖ¸é µÊ.
805                        }
806                        else if (cmd.idCmd == eTASK_CMD_SHOW) {
807                                p_show_scheduled_cmd(xt, &cmd);
808                        }
809                        else if (cmd.idCmd == eTASK_CMD_QUERY) {
810                                // not yet..
811                        }
812                        else if (cmd.idCmd == eTASK_CMD_SHUTDOWN) {
813                                break;
814                        }
815
816                        if (cmd.idCmd == eTASK_CMD_SYNC) {
817                                DHL_OS_GiveSemaphore(xt->pti.semAck);
818                        }
819                }
820                else if (result == DHL_FAIL_TIMEOUT)
821                {
822                        // À̰ÍÀº ¿¡·¯°¡ ¾Æ´Ï´Ù. ¿¹¾à ¸í·É Áß Çϳª¸¦ ½ÇÇàÇÒ ¶§°¡ µÇ¾úÀ½À» ³ªÅ¸³½´Ù.
823                }
824                else 
825                {
826                        dprint(0, "!! task rx msg result 0x%x\a\n", result);
827                }
828
829                //-------- scheduled cmd list ó¸® ---------------
830
831                /* ¿¹¾à ¸í·É ¸®½ºÆ®¸¦ ¸ðµÎ üũÇÏ¿© ½Ã°£ °æ°ú µÈ ¸í·ÉµéÀ» ¸ðµÎ ó¸®ÇØ ÁØ´Ù.
832                */
833                for (i=0; i<=xt->maxActiveIndex; i++)
834                {
835                        S_OSX_CMD_SCHED *psc = &xt->sclist[i];
836               
837                        if (psc->used == FALSE)
838                                continue;
839                               
840                        // ÁöÁ¤ ½Ã°£ÀÌ °æ°úµÇ¾ú´ÂÁö üũ. Timeout µÇ¾úÀ¸¸é TimerÇÔ¼ö ¼öÇà.
841                        //
842                        if (DHL_OS_GetMsCount() - psc->start > psc->period) // Timer expired..
843                        {
844                                S_OSX_CMD_SCHED schcmd = *psc;
845                                BOOL bOneShot = (schcmd.flags & eTASK_FLAG_Repeat) ? 0 : 1;
846                               
847                                if (bOneShot) {  // 1ȸ ½ÇÇà ¸í·É. ÀÌ entry¸¦ »èÁ¦ ÇÑ´Ù.
848                                        memset(psc, 0, sizeof(S_OSX_CMD_SCHED));
849                                        xt->nScheduledCmd--;
850                                }
851                                else {   // ¹Ýº¹ ½ÇÇà ¸í·É. timer counter¸¦ ¸®¼Â½ÃŲ´Ù.
852                                        psc->start = DHL_OS_GetMsCount();
853                                }
854
855                                p_callback_user_func(xt, schcmd.idCmd, schcmd.flags, schcmd.fn, schcmd.params);
856
857                                if (bOneShot)
858                                        if (s_osx_traced == xt)
859                                        dprint(0, "oneshot cmd %x serviced\n", schcmd.idCmd);
860                        }
861                       
862                } // end for (sch cmd list)
863               
864        }
865
866        p_shutdown_task(xt);
867
868}
869
870
871#if COMMENT
872____API____(){}
873#endif
874
875
876
877DHL_RESULT OSX_TaskRegisterCmdV(H_OSX_TASK handle, T_OSX_TASK_CMD nIdCmd, UINT32 nDelayMs, 
878                                                UINT16 flags, F_OSX_TASK_PROC func, va_list param)
879{
880        DHL_RESULT dhr;
881        S_OSX_TASK_PUBLIC pti0, *pti;
882        S_OSX_TASK_CMD cmd;
883        DHL_OS_TASK_ID tid = DHL_OS_GetTaskID();
884        va_list arg;
885        int i;
886
887        pti = p_get_osx_task(handle, &pti0); // get public task info
888        if (pti == NULL)
889                return DHL_FAIL_INVALID_HANDLE;
890
891        if (func == NULL) {
892                dprint(0, "!! func is null [cmd %x]!\n", nIdCmd);
893                return DHL_FAIL_INVALID_PARAM;
894        }
895        if (nIdCmd >= eTASK_CMD_BEGIN || nIdCmd == 0) {
896                dprint(0, "!! cmd id 0x%x is in reserved range.\n", nIdCmd);
897                DHL_ASSERT(FALSE, "");
898                return DHL_FAIL_INVALID_PARAM;
899        }
900        if (nDelayMs == 0 && (flags & eTASK_FLAG_Repeat)) {
901                dprint(0, "!! interval timer should have period.\n");
902                DHL_ASSERT(FALSE, "");
903                return DHL_FAIL_INVALID_PARAM;
904        }
905       
906        dprint(2, "%s: (cmd 0x%x, period %d, flags 0x%x)\n", __func__, 
907                nIdCmd, nDelayMs, flags);
908
909        memset(&cmd, 0, sizeof(S_OSX_TASK_CMD));
910
911        cmd.idCmd = nIdCmd;
912        cmd.snTask = SERIAL_FROM_HANDLE(handle);
913        cmd.nDelayMs = nDelayMs;
914        cmd.func = func;
915        cmd.flags = flags;
916
917        for (i=0; i<pti->nCmdParam; i++)
918                cmd.params[i] = va_arg(param, UINT32);
919       
920        if (tid != pti->tid)
921        {
922                // cmd ÀÚü´Â ÃÖ´ë °¹¼öÀÇ user paramÀ» Æ÷ÇÔÇϰí ÀÖÁö¸¸
923                // OSAL ³»ºÎ¿¡¼­ ÇÊ¿äÇÑ ¸¸Å­¸¸ º¹»ç¸¦ ÇØ °¥ °ÍÀÌ´Ù.
924                dhr = DHL_OS_SendMessage(pti->msgQue, &cmd, sizeof(cmd));
925                // error check..
926                if (dhr == DHL_FAIL_BUSY) {
927                        dprint(0, "!! %s queue full\a\n", __func__);
928                        // 0x18: DHL_FAIL_BUSY ´Â queue full ³ª¸é ¹ß»ýÇÔ.
929                }
930                else if (dhr) {
931                        dprint(0, "!! %s send cmd err %x\a\n", __func__, dhr);
932                }               
933        }
934        else
935        {
936                // current task is THE Task that we can add.
937                // so, we can directly modify task variable.
938                //
939                dhr = p_add_scheduled_cmd(pti->xt, &cmd);
940        }
941        return dhr;
942}
943
944/*
945        Task¿¡ ¸í·É ¿¹¾à. ¹Ýº¹ ¼³Á¤ °¡´É.
946*/
947DHL_RESULT OSX_TaskScheduleCmd(H_OSX_TASK handle, T_OSX_TASK_CMD nIdCmd, UINT32 nDelayMs, 
948                                                UINT16 flags, F_OSX_TASK_PROC func, ...)
949{
950        DHL_RESULT dhr;
951        va_list ap;
952       
953        va_start(ap, func);
954        dhr = OSX_TaskRegisterCmdV(handle, nIdCmd, nDelayMs, flags, func, ap); 
955        va_end(ap);
956
957        return dhr;
958}
959
960/*
961        Task¿¡¼­ ¸í·É ½ÇÇà.
962*/
963DHL_RESULT OSX_TaskRunCmd(H_OSX_TASK handle, T_OSX_TASK_CMD nIdCmd,
964                                                UINT16 flags, F_OSX_TASK_PROC func, ...)
965{
966        DHL_RESULT dhr;
967        va_list ap;
968
969        // Áö¿¬, ¹Ýº¹ ¿É¼ÇÀº Á¦°Å.
970        flags &= ~(eTASK_FLAG_Delayed | eTASK_FLAG_Repeat);
971       
972        va_start(ap, func);
973        dhr = OSX_TaskRegisterCmdV(handle, nIdCmd, 0/* no delay */, flags, func, ap);
974        va_end(ap);
975
976        return dhr;
977}
978
979
980/*
981        ¹Ýº¹ ¼³Á¤ µÈ (¶Ç´Â Áö¿¬ ½ÇÇà µî·ÏµÇ°í ¾ÆÁ÷ ½ÇÇàÀº ¾ÈµÈ) ¸í·ÉÀÇ Ãë¼Ò.
982*/
983DHL_RESULT OSX_TaskStopCmd(H_OSX_TASK handle, T_OSX_TASK_CMD nIdCmd)
984{
985        DHL_RESULT dhr;
986        S_OSX_TASK_PUBLIC pti0, *pti;
987        S_OSX_TASK_CMD cmd;
988        DHL_OS_TASK_ID tid = DHL_OS_GetTaskID();
989       
990        pti = p_get_osx_task(handle, &pti0);
991        if (pti == NULL)
992                return DHL_FAIL_INVALID_HANDLE;
993
994        if (nIdCmd == 0 || nIdCmd >= eTASK_CMD_BEGIN) {
995                dprint(0, "!! invalid cmd %x\n", nIdCmd);
996                return DHL_FAIL_INVALID_PARAM;
997        }
998
999        memset(&cmd, 0, sizeof(S_OSX_TASK_CMD));
1000
1001        cmd.idCmd = eTASK_CMD_DELETE;
1002        cmd.snTask = SERIAL_FROM_HANDLE(handle);
1003        cmd.params[0] = nIdCmd;
1004       
1005        if (tid != pti->tid)
1006        {
1007                dhr = DHL_OS_SendMessage(pti->msgQue, &cmd, sizeof(cmd));
1008                if (dhr == DHL_FAIL_BUSY) {
1009                        dprint(0, "!! %s queue full\a\n", __func__);
1010                        // 0x18: DHL_FAIL_BUSY ´Â queue full ³ª¸é ¹ß»ýÇÔ.
1011                }
1012                else if (dhr) {
1013                        dprint(0, "!! %s send cmd err %x\a\n", __func__, dhr);
1014                }
1015        }
1016        else
1017        {
1018                // current task is THE TIMER task that we can add.
1019                // so, we can directly modify timer variable.
1020                //
1021                dhr = p_del_scheduled_cmd(pti->xt, nIdCmd);
1022        }
1023        return dhr;
1024}
1025
1026
1027DHL_RESULT OSX_TaskSync(H_OSX_TASK handle)
1028{
1029        DHL_RESULT dhr;
1030        S_OSX_TASK_PUBLIC pti0, *pti;
1031        S_OSX_TASK_CMD cmd;
1032        DHL_OS_TASK_ID tid = DHL_OS_GetTaskID();
1033       
1034        pti = p_get_osx_task(handle, &pti0);
1035        if (pti == NULL)
1036                return DHL_FAIL_INVALID_HANDLE;
1037
1038        memset(&cmd, 0, sizeof(S_OSX_TASK_CMD));
1039
1040        cmd.idCmd = eTASK_CMD_SYNC;
1041        cmd.snTask = SERIAL_FROM_HANDLE(handle);
1042       
1043        if (tid != pti->tid)
1044        {
1045                int wait_count;
1046
1047                // need ack mechanism..
1048                DHL_OS_TakeSemaphore(pti->mutexAck, DHL_TIMEOUT_FOREVER);
1049
1050                // mutex wait µµÁß¿¡ task°¡ shutdown µÇ¾úÀ» ¼ö ÀÖ´Ù.
1051                pti = p_get_osx_task(handle, &pti0);
1052                if (pti == NULL) {
1053                        dprint(0, "!! task stop while wait sync..\n");
1054                        dhr = DHL_FAIL;
1055                        goto end_mutex;
1056                }
1057                DHL_OS_TakeSemaphore(pti->semAck, 0); // reset to none
1058               
1059                dhr = DHL_OS_SendMessage(pti->msgQue, &cmd, sizeof(cmd));
1060                if (dhr == DHL_FAIL_BUSY) {
1061                        dprint(0, "!! %s queue full\a\n", __func__);
1062                        // 0x18: DHL_FAIL_BUSY ´Â queue full ³ª¸é ¹ß»ýÇÔ.
1063                        goto end_mutex;
1064                }
1065                else if (dhr) {
1066                        dprint(0, "!! %s send cmd err %x\a\n", __func__, dhr);
1067                        // ¿¡·¯°¡ ¹ß»ýÇß´Ù¸é wait ÇÏ´Â °ÍÀº Àǹ̰¡ ¾ø°Ô µÈ´Ù. ¿¡·¯ ¾ø´Â °æ¿ì¿¡¸¸ ÁøÇà.
1068                        goto end_mutex;
1069                }
1070                /* ÀÌ sync ¸í·É º¸´Ù ¸ÕÀú shutdown ¸í·ÉÀÌ ÀÖ´ø °æ¿ì¶ó¸é
1071                        ack ÀÀ´äÀº ¾È ¿Ã ¼ö ÀÖÀ½.
1072                */
1073                for (wait_count=0 ; wait_count<5; wait_count++) {
1074                        if (wait_count)
1075                                dprint(0, "!! task (handle %x) not responding.. wait %d..\n", 
1076                                        handle, wait_count);
1077                        dhr = DHL_OS_TakeSemaphore(pti->semAck, 1000);
1078                        if (dhr == DHL_OK) break;
1079                }
1080end_mutex:
1081                DHL_OS_GiveSemaphore(pti->mutexAck);
1082        }
1083        else
1084        {
1085                dprint(0, "!! sync called inside task\n");
1086                //DHL_ASSERT(FALSE, "invalid usage\n");
1087        }
1088        return dhr;
1089}
1090
1091/*
1092        taskÀÇ °£´ÜÇÑ Á¤º¸ ¹× ¿¹¾à µÈ ¸í·Éµé È­¸é Ãâ·Â.
1093*/
1094void OSX_TaskShow(H_OSX_TASK handle)
1095{
1096        DHL_RESULT dhr;
1097        S_OSX_TASK_PUBLIC pti0, *pti;
1098        S_OSX_TASK_CMD cmd;
1099        DHL_OS_TASK_ID tid = DHL_OS_GetTaskID();
1100
1101        if (handle == 0)
1102        {
1103                // ÇöÀç µ¿ÀÛÁßÀÎ ¸ðµç task list¸¸ Ãâ·Â.
1104                H_OSX_TASK list[OSX_MAX_TASK];
1105                int i, n_task;
1106                n_task = p_list_all_osx_task(list);
1107                for(i=0; i<n_task; i++)
1108                        DHL_OS_Printf(" (%d) %x\n", i, list[i]);
1109                return;
1110        }
1111
1112        pti = p_get_osx_task(handle, &pti0);
1113        if (pti == NULL)
1114                return;
1115       
1116        do 
1117        {
1118                memset(&cmd, 0, sizeof(S_OSX_TASK_CMD));
1119                cmd.idCmd = eTASK_CMD_SHOW;
1120                cmd.snTask = SERIAL_FROM_HANDLE(handle);
1121                // this SHOW command do not use ACK.
1122
1123                if (tid != pti->tid) {
1124                        // send command asynchronously..
1125                        dhr = DHL_OS_SendMessage(pti->msgQue, &cmd, sizeof(cmd));
1126                        if (dhr) {
1127                                // error check..
1128                                dprint(0, "!! %s send cmd err %x\a\n", __func__, dhr);
1129                        }
1130                }
1131                else {
1132                        p_show_scheduled_cmd(pti->xt, &cmd);
1133                }
1134
1135                if (handle) // show only specified task.
1136                        break;
1137                       
1138                if (tid != pti->tid) {
1139                        //DHL_OS_Delay(100);
1140                                // wait for timer tasks to print information
1141                }
1142               
1143        }while (0);
1144       
1145}
1146
1147
1148/*
1149
1150*/
1151void OSX_TaskGetInfo(H_OSX_TASK handle, S_OSX_TASK_INFO *pinfo)
1152{
1153        S_OSX_TASK_PUBLIC pti0, *pti;
1154
1155        pti = p_get_osx_task(handle, &pti0); // get public task info
1156
1157        if (pinfo)      {
1158                pinfo->tid = pti ? pti->tid : 0;
1159        }
1160}
1161
1162
1163
1164#if COMMENT
1165____API____(){}
1166#endif
1167
1168void OSX_TaskGetDefaultInitSetting(S_OSX_TASK_INIT_SETTING *setting)
1169{
1170        if (setting) {
1171                memset(setting, 0, sizeof(*setting));
1172                setting->name = "";
1173                setting->max_scheduled_cmd = 4;
1174                setting->priority = 32;
1175                setting->stack_size = 8192;
1176                //setting->num_cmd_param = 1;
1177                setting->msg_que_size = 2;
1178        }
1179}
1180
1181/*
1182
1183*/
1184DHL_RESULT OSX_TaskStart(S_OSX_TASK_INIT_SETTING *setting, H_OSX_TASK *pHandle)
1185{
1186        DHL_RESULT dhlResult = DHL_OK;
1187        char buf[20];
1188        S_OSX_TASK *xt;
1189        H_OSX_TASK handle = 0;
1190        DHL_OS_TASK_ID tid = 0;
1191
1192        osx_module_init();
1193
1194        dprint(2, "%s: '%s', prio %d, stack %d, qsize %d, #param %d, max delayed cmd %d\n", 
1195                        __func__, setting->name, 
1196                        setting->priority, setting->stack_size, setting->msg_que_size,
1197                        setting->num_cmd_param, setting->max_scheduled_cmd, 
1198                        0);
1199
1200        *pHandle = 0; // initialize first..
1201
1202        //------- check settings parameter
1203       
1204        if (setting->max_scheduled_cmd <= 0) {
1205                dprint(0, "!! max sched cmd %d invalid.\n", setting->max_scheduled_cmd);
1206                dhlResult = DHL_FAIL_INVALID_PARAM;
1207                //DHL_ASSERT(FALSE, "");
1208                goto label_end;
1209        }
1210        if (setting->num_cmd_param < 0 || setting->num_cmd_param > OSX_MAX_CMD_PARAMS) {
1211                dprint(0, "!! num user param %d invalid.\n", setting->num_cmd_param);
1212                dhlResult = DHL_FAIL_INVALID_PARAM;
1213                //DHL_ASSERT(FALSE, "");
1214                goto label_end;
1215        }
1216        if (setting->msg_que_size < 0) {
1217                dprint(0, "!! que size %d invalid.\n", setting->msg_que_size);
1218                dhlResult = DHL_FAIL_INVALID_PARAM;
1219                goto label_end;
1220        }
1221
1222
1223        //------- allocate osx task
1224        xt = p_alloc_osx_task();
1225        if (!xt) {
1226                dprint(0, "!! no more available osx task\n");
1227                dhlResult = DHL_FAIL_OUT_OF_RESOURCE;
1228                goto label_end;
1229        }       
1230
1231        //------- initialize task variables     
1232        //memset(xt, 0, sizeof(*xt)); // done in alloc_osx_task().
1233
1234        // name of timers
1235        strncpy(xt->name, setting->name, OSX_MAX_TASK_NAME);
1236        xt->name[OSX_MAX_TASK_NAME] = 0;
1237
1238        // max timer slots
1239        xt->nMaxSlot = setting->max_scheduled_cmd;
1240       
1241        // no active timer now.
1242        xt->maxActiveIndex = -1;
1243
1244        xt->sclist = (S_OSX_CMD_SCHED *) DHL_OS_Malloc(
1245                        setting->max_scheduled_cmd* sizeof(S_OSX_CMD_SCHED) + 4);
1246                        // 4 is margin.
1247        if (xt->sclist == NULL) {
1248                dhlResult = DHL_FAIL_OUT_OF_MEMORY;
1249                goto label_end;
1250        }
1251
1252        // message que size
1253        if (setting->msg_que_size == 0)
1254                xt->nMaxQueSize = OSX_DEFAULT_MSG_QUE_SIZE; // for backward compatibility
1255        else if (setting->msg_que_size > 0)
1256                xt->nMaxQueSize = setting->msg_que_size;
1257
1258        //------ preprare public task info ------
1259
1260        // num user param
1261        if (setting->num_cmd_param <= 0)
1262                // ÃÖ¼ÒÇÑ 1°³ÀÇ ÆÄ¶ó¹ÌÅÍ °ø°£Àº ÇÊ¿äÇÏ´Ù. ³»ºÎ ¸í·É Áß¿¡ ÀÌ ¿µ¿ªÀ» »ç¿ëÇÏ´Â °ÍµéÀÌ ÀÖÀ½.
1263                xt->pti.nCmdParam = 1;
1264        else
1265                xt->pti.nCmdParam = setting->num_cmd_param;
1266
1267        // task´Â ¸Ç ¸¶Áö¸·¿¡ »ý¼ºÇÏ´Â °Ô ÁÁ´Ù. priority °ü·ÃÇÏ¿© ¸ÕÀú ½ÇÇà °¡´É¼ºÀÌ ÀÖÀ¸¹Ç·Î..
1268        //
1269       
1270        memset(buf, 0, sizeof(buf));
1271        strcpy(buf, "TS");      // task ack sem
1272        strncpy(buf+2, xt->name, 6);
1273        xt->pti.semAck = DHL_OS_CreateBinarySemaphore(buf, 0, 0);
1274       
1275        if (xt->pti.semAck == 0) {
1276                dprint(0, "!! Creating sem err\n");
1277                dhlResult = DHL_FAIL_OUT_OF_RESOURCE;
1278                goto label_end;
1279        }
1280
1281        memset(buf, 0, sizeof(buf));
1282        strcpy(buf, "TM");      // task ack mutex
1283        strncpy(buf+2, xt->name, 6);
1284        xt->pti.mutexAck = DHL_OS_CreateMutexSemaphore(buf);
1285
1286        if (xt->pti.mutexAck == 0) {
1287                dprint(0, "!! Creating mutex err\n");
1288                dhlResult = DHL_FAIL_OUT_OF_RESOURCE;
1289                goto label_end;
1290        }
1291
1292        memset(buf, 0, sizeof(buf));
1293        strcpy(buf, "TQ");      // task cmd que
1294        strncpy(buf+2, xt->name, 6);
1295
1296        xt->pti.msgQue = DHL_OS_CreateMessageQueue(buf, 0, 
1297                xt->nMaxQueSize, OSX_COMMAND_SIZE(xt->pti.nCmdParam));
1298
1299        if (xt->pti.msgQue == 0) {
1300                dprint(0, "!! Creating msgq err\n");
1301                dhlResult = DHL_FAIL_OUT_OF_RESOURCE;
1302                goto label_end;
1303        }
1304        xt->pti.xt = xt; // self.
1305
1306        xt->setting = *setting;
1307        xt->setting.name = xt->name;
1308
1309        //------- launch task
1310
1311        handle = MAKE_OSX_HANDLE(xt->index, xt->serial);
1312        /*
1313                task priority°¡ ³ôÀ» °æ¿ì ÀÌ ÇÔ¼ö°¡ Á¾·áµÇÁö Àü¿¡µµ ¹Ù·Î task°¡
1314                ½ÇÇà µÉ ¼ö ÀÖÀ½¿¡ À¯ÀÇÇÒ °Í.
1315        */
1316        tid = DHL_OS_CreateTask((DHL_OS_TASKFUNCTION) p_task_main, xt->name, 
1317                                                setting->priority, setting->stack_size, (UINT32)xt);
1318
1319        if (tid == (DHL_OS_TASK_ID) 0) {
1320                dprint(0, "!! osx task create err\n");
1321                dhlResult = DHL_FAIL_OUT_OF_RESOURCE;
1322                goto label_end;
1323        }
1324
1325        p_validate_osx_task(xt); // now, xt is "VALID"
1326        xt->pti.tid = tid;      // now, task is running.
1327
1328        if (pHandle)
1329                *pHandle = handle;
1330        xt = 0;
1331
1332label_end:
1333       
1334        if (xt) {
1335                // clean up!
1336                dprint(0, "!! err occurred in task init. clean up!\n");
1337
1338                if (xt->sclist)
1339                        DHL_OS_Free((void **)&xt->sclist);
1340                if (xt->pti.semAck)
1341                        DHL_OS_DeleteSemaphore(xt->pti.semAck);
1342                if (xt->pti.mutexAck)
1343                        DHL_OS_DeleteSemaphore(xt->pti.mutexAck);
1344                if (xt->pti.msgQue)
1345                        DHL_OS_DeleteMessageQueue(xt->pti.msgQue);
1346               
1347                p_free_osx_task(xt);
1348        }
1349        return dhlResult;
1350}
1351
1352
1353/**
1354        @todo
1355                Task Á¾·á OSAL API°¡ ¾ø´Ù¸é internal ¿ëµµÀÇ functionÀ» ¸¸µé¾î¼­
1356                OSAL_Priv.h ¿¡ µî·ÏÇØ ³õ°í »ç¿ëÇÏ¸é µÉ °Í °°À½.
1357               
1358*/
1359void OSX_TaskShutdown(H_OSX_TASK handle)
1360{
1361        DHL_RESULT dhlResult;
1362        S_OSX_TASK_PUBLIC pti0, *pti;
1363        UINT32 i;
1364        S_OSX_TASK_CMD cmd;
1365        DHL_OS_TASK_ID tid = DHL_OS_GetTaskID();
1366
1367        osx_module_init();
1368
1369        // TimerTask°¡ ÀÚµ¿À¸·Î Á×À»¶§±îÁö ±â´Ù¸± ½Ã°£..
1370#define WAIT_TIME         1 // second.
1371#define CHECK_PER_SECOND  10 // times.
1372
1373        pti = p_get_osx_task(handle, &pti0);
1374        if (pti == NULL) {
1375                dprint(0, "!! invalid osx task handle %x\n", handle);
1376                return;
1377        }
1378
1379        if (tid == pti->tid) {
1380                dprint(0, "!! %s: cannot shutdown timer in itself\n", __func__);
1381                return;
1382        }
1383
1384        memset(&cmd, 0, sizeof(S_OSX_TASK_CMD));
1385        cmd.idCmd = eTASK_CMD_SHUTDOWN;
1386
1387        dhlResult = DHL_OS_SendMessage(pti->msgQue, &cmd, sizeof(cmd));
1388        if (dhlResult) {
1389                // error check..
1390                dprint(0, "!! %s send cmd err %x\n", __func__, dhlResult);
1391        }
1392        else {
1393                for (i = 0; i < WAIT_TIME*CHECK_PER_SECOND; ++i) {
1394                        if (pti->tid == 0) {
1395                                break;
1396                        }
1397                        DHL_OS_Delay(1000/CHECK_PER_SECOND);
1398                }
1399               
1400                // ÃæºÐÈ÷ ±â´Ù·È°Ç¸¸, Self Delete°¡ µÇÁö ¾Ê¾ÒÀ» °æ¿ì ¿¡·¯ ¸Þ½ÃÁö.
1401                //
1402                if (pti->tid != 0) {
1403                        dprint(0, "!! osx task shutdown timeout!\n");
1404                }
1405        }
1406        pti->tid = 0;
1407
1408}
1409
1410
1411
1412#if COMMENT
1413____Symbol____(){}
1414#endif
1415
1416#if DHL_REGISTER_DEUBG_SYMBOLS
1417static DHL_SymbolTable _symbols[] =
1418{
1419        //---- functions
1420        //DHL_FNC_SYM_ENTRY(xxx),
1421       
1422        //---- variables
1423        DHL_VAR_SYM_ENTRY(s_osx_traced),
1424       
1425};
1426#endif // DHL_REGISTER_DEBUG_SYMBOL
1427
1428
1429
1430#if COMMENT
1431____Init____(){}
1432#endif
1433
1434void osx_module_init(void)
1435{
1436        if (s_module_init)
1437                return;
1438
1439        s_osx_mutex = DHL_OS_CreateMutexSemaphore("OSX");
1440        DHL_ASSERT(s_osx_mutex != 0, "");
1441
1442#if DHL_REGISTER_DEUBG_SYMBOLS
1443        DHL_DBG_RegisterSymbols(_symbols, DHL_NUMSYMBOLS(_symbols));
1444#endif 
1445
1446        s_module_init = TRUE;
1447}
1448
1449void osx_trace(UINT32 handle)
1450{
1451        S_OSX_TASK_PUBLIC pti0, *pti;
1452        pti = p_get_osx_task(handle, &pti0);
1453        if (!pti) {
1454                dprint(0, "!! invalid handle %x\n", handle);
1455                return;
1456        }
1457        dprint(0, "trace osx task handle %x, task %x\n", handle, pti->xt);
1458        s_osx_traced = pti->xt;
1459}
1460
1461
1462#if COMMENT
1463____Test____(){}
1464#endif
1465
1466#if 1 // test
1467
1468#define printf DHL_OS_Printf
1469
1470H_OSX_TASK s_osx_test_handle;
1471void osx_test_init(void)
1472{
1473        DHL_RESULT dhr;
1474        S_OSX_TASK_INIT_SETTING stg;
1475
1476        if (s_osx_test_handle) {
1477                printf("already run\n");
1478                return;
1479        }
1480        OSX_TaskGetDefaultInitSetting(&stg);
1481        stg.num_cmd_param = 2;
1482        dhr = OSX_TaskStart(&stg, &s_osx_test_handle);
1483        if (dhr)
1484                printf("!! task start err %x\n", dhr);
1485        else
1486                printf("task handle %x\n", s_osx_test_handle);
1487}
1488
1489void osx_test_uninit(void)
1490{
1491        if (s_osx_test_handle == 0)
1492                return;
1493
1494        OSX_TaskShutdown(s_osx_test_handle);
1495        s_osx_test_handle = 0;
1496}
1497
1498static void osx_cmd_1(int cmd, int arg1, int arg2)
1499{
1500        printf("**** cmd %x, arg %x %x\n", cmd, arg1, arg2);   
1501}
1502static void osx_cmd_4(int cmd, int arg1, int arg2)
1503{
1504        printf("**** cmd %x, wait %d sec..\n", cmd, arg1);
1505        DHL_OS_Delay(arg1*1000);
1506        printf("---- cmd exec end\n");
1507}
1508
1509void osx_test_stop(int cmd)
1510{
1511        OSX_TaskStopCmd(s_osx_test_handle, cmd);
1512}
1513void osx_test_run1(int arg1, int arg2)
1514{
1515        OSX_TaskRunCmd  (s_osx_test_handle, 1, 0, (F_OSX_TASK_PROC)osx_cmd_1, arg1, arg2);
1516}
1517void osx_test_run2(int wait) // delayed
1518{
1519        OSX_TaskScheduleCmd(s_osx_test_handle, 2, wait*1000, eTASK_FLAG_Delayed, (F_OSX_TASK_PROC)osx_cmd_1, 0, 0);
1520}
1521void osx_test_run3(int period) // repeat
1522{
1523        OSX_TaskScheduleCmd(s_osx_test_handle, 3, period*1000, eTASK_FLAG_Repeat, (F_OSX_TASK_PROC)osx_cmd_1, 0, 0);
1524}
1525void osx_test_run4(int arg1, int arg2) //
1526{
1527        OSX_TaskRunCmd  (s_osx_test_handle, 4, 0, (F_OSX_TASK_PROC)osx_cmd_4, arg1, arg2);
1528}
1529
1530/*
1531        sml osx 3
1532        osx_test_init
1533        osx_trace 0x10001
1534
1535        OSX_TaskShow
1536        OSX_TaskShow 0x10001
1537
1538        // basic dpc test
1539        osx_test_run1 0x33 0x44
1540
1541        // delayed exec test
1542        osx_test_run2 1 
1543        osx_test_run2 2
1544        osx_test_run2 5
1545        osx_test_stop 2
1546       
1547        // repeat exec test
1548        osx_test_run3 1
1549        osx_test_stop 3
1550       
1551        // queue full test
1552        osx_test_run4 5
1553        osx_test_run1
1554        osx_test_run1
1555        osx_test_run1
1556                !! OSX_TaskRegisterCmdV send cmd err 18
1557        osx_test_run1
1558
1559*/
1560#endif // test
1561
1562
1563
1564/* end of file */
1565
Note: See TracBrowser for help on using the repository browser.