]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-rtos/netapi.git/blob - ti/runtime/netapi/src/netapi_timer.c
c1c6df516c3552e377abbe81803021dba7580442
[keystone-rtos/netapi.git] / ti / runtime / netapi / src / netapi_timer.c
1 /*******************************
2  * FILE: netapi_timer.c
3  * Purpose:  implementation of user space timers 
4  **************************************************************
5  * FILE: netapi.c
6  * 
7  * DESCRIPTION:  user space timers main source file for user space transport
8  *               library
9  * 
10  * REVISION HISTORY:  rev 0.0.1 
11  *
12  *  Copyright (c) Texas Instruments Incorporated 2010-2011
13  * 
14  *  Redistribution and use in source and binary forms, with or without 
15  *  modification, are permitted provided that the following conditions 
16  *  are met:
17  *
18  *    Redistributions of source code must retain the above copyright 
19  *    notice, this list of conditions and the following disclaimer.
20  *
21  *    Redistributions in binary form must reproduce the above copyright
22  *    notice, this list of conditions and the following disclaimer in the 
23  *    documentation and/or other materials provided with the   
24  *    distribution.
25  *
26  *    Neither the name of Texas Instruments Incorporated nor the names of
27  *    its contributors may be used to endorse or promote products derived
28  *    from this software without specific prior written permission.
29  *
30 *
31  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
32  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
33  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
35  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
36  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
37  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
38  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
39  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
40  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
41  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42  *
43  ***************************************************************/
44 #include "netapi.h"
45 #include "netapi_timer.h"
46 #include "timer_loc.h"
49 /*******************************************************************
50  *  hash function:  returns cell to place timer object in
51  *   
52  ******************************************************************/
53 /* static */ int our_hash(
54        unsigned long long ct,
55        int n_cells,
56        unsigned int cell_width)
57 {
58 int c;
59    //simple hash function
60    c=  (ct/cell_width) % n_cells;
61   return c;
63 }
65 //iterator on TIMER_LIST_T
66 NETAPI_TIMER_T netapi_TimerGetFirst( NETAPI_TIMER_LIST_T list)
67 { return (NETAPI_TIMER_T) ((TIM_LIST_T *)list)->head; }
69 NETAPI_TIMER_T netapi_TimerGetNext( NETAPI_TIMER_LIST_T list,NETAPI_TIMER_T prev)
70 {return prev ? (NETAPI_TIMER_T) ((TIM_T*) prev)->next:NULL ;}
72 //return cookie associated with timer object 
73 void * netapi_TimerGetCookie(NETAPI_TIMER_T timer)
74 { return ((TIM_T*) timer)->cookie; }
76 //return timeer value associated with timer object 
77 unsigned long long netapi_TimerGetTs(NETAPI_TIMER_T timer)
78 { return ((TIM_T*) timer)->t; }
80 #if 0
81 //timer callback
82 typedef void (*NETAPI_TIMER_CB_T) (
83         NETAPI_TIMER_GROUP_HANDLE_T th,
84         int n_fired,     //# timers fired
85         NETAPI_TIMER_LIST_T fired_list,
86         uint64_t currentTime);
87 #endif
89 static TIMER_GROUP_T temp_g; //temp. todo: put inot netHandle
91 //create a timer group
92 NETAPI_TIMER_GROUP_HANDLE_T netapi_TimerGroupCreate(
93         NETAPI_T  netHandle,
94         char * name,
95         NETAPI_TIMER_CB_T cb,
96         int local,    //1 if timers local to thread
97         int exp2cancel,//1 if expect to cancel
98         int cell_width, //in ticks
99         int tol,        //in ticks
100         int maxTimers,
101         int *pErr)
103  int ret= tim_group_create(&temp_g, TUNE_NETAPI_NUM_TIMER_CELLS, maxTimers);
104  if (!ret) {*pErr = NETAPI_ERR_NOMEM; return NULL;}
105  *pErr=0;
106  temp_g.cb = cb;
107  temp_g.local = local;
108  temp_g.exp2cancel= exp2cancel;
109  temp_g.cell_width=cell_width;
110  temp_g.tol=tol;
111  temp_g.h = netHandle;
112  temp_g.last_polled=(netapi_getTimestamp()/cell_width) * cell_width + (cell_width-1);
113  printf(">timer group %s created. width = %d (ticks)\n", name, cell_width);
114  return (NETAPI_TIMER_GROUP_HANDLE_T) &temp_g;
117 //open a [global] timer group
118 NETAPI_TIMER_GROUP_HANDLE_T  netapi_TimerGroupOpen(
119         NETAPI_T netHandle,
120         char * name,
121         NETAPI_TIMER_CB_T cb,
122         int *pErr)
124 printf(">timer group open not implemented \n");
128 //start an individual timer
129 NETAPI_TIMER_T netapi_TimerGroupStartTimer(
130         NETAPI_TIMER_GROUP_HANDLE_T th,
131         void * cookie,
132         uint64_t offs2fire,  //offset in group ticks 
133         int * pErr)
135 TIM_T * timer_obj;
136 unsigned long long ct= netapi_getTimestamp() + offs2fire* ((TIMER_GROUP_T*) th)->cell_width;
137 int cell;
138 *pErr=0;
140 //find cell where to insert
141 cell = our_hash(ct,((TIMER_GROUP_T*) th)->n_cells , ((TIMER_GROUP_T*) th)->cell_width);
143 //get object and insert into this cell
144 timer_obj =tim_set(
145    &((TIMER_GROUP_T*) th)->cells[cell],
146    &((TIMER_GROUP_T*) th)->free , 
147    ct,
148    cookie,
149    pErr);
150 if (!timer_obj)  {return NULL;}
151 printf(">timer: setting timer %x for %lld ticks -> hased to cell %d\n",cookie, ct,cell);
152 return (NETAPI_TIMER_T) timer_obj;
155 //Cancel a timer
156 void  netapi_TimerGroupCancel(
157         NETAPI_TIMER_GROUP_HANDLE_T th,
158         NETAPI_TIMER_T timerId,
159         int *pErr)
161     tim_cancel((TIM_T *) timerId, pErr);
164 //close an opened timer group
165 void netapi_TimerGroupClose(
166         NETAPI_TIMER_GROUP_HANDLE_T th,
167         int *pErr){}
169 //delete atimer group
170 void netapi_TimerGroupDelete(
171         NETAPI_TIMER_GROUP_HANDLE_T th,
172         int *pErr) {printf(">timer group delete not implemented\n");}
174 //extract netapi handle from timer group handle
175 NETAPI_T netap_TimerGroupGetNH( NETAPI_TIMER_GROUP_HANDLE_T th) { return ((TIMER_GROUP_T*) th)->h; }
178 //-----for timer debuggingi-------
179 struct
181 //last poll stats
182 int n_tot;
183 int c_seen;
185 int max_c_seen;
186 int max_n_tot;
188 } timer_poll_stats;
189 void dump_poll_stats(void)
191   printf("debug timer poll> n_tot=%d c_seen=%d mnt=%d mcs=%d\n",
192              timer_poll_stats.n_tot, timer_poll_stats.c_seen,
193              timer_poll_stats.max_n_tot, timer_poll_stats.max_c_seen);
195 //-------end timer debugging----
197 //poll a specific timer group
198 int  netapi_TimerGroupPoll(NETAPI_TIMER_GROUP_HANDLE_T th, int maxTimers)
200 unsigned long long ct= netapi_getTimestamp(); 
201 unsigned long long i;
202 int cell;
203 TIM_LIST_T res;
204 int n;
205 int n_tot=0;
206 int c_seen=0;
208    for(i=((TIMER_GROUP_T*) th)->last_polled; (i<= ct) && (n_tot<maxTimers); )
209    {
210       cell =  our_hash(i,((TIMER_GROUP_T*) th)->n_cells , ((TIMER_GROUP_T*) th)->cell_width); 
211       tim_return_fired_list(&((TIMER_GROUP_T*) th)->cells[cell],
212                             &res,
213                             &((TIMER_GROUP_T*) th)->free,
214                             i,  
215                             &n);
216       if (n)
217       {
218            ((TIMER_GROUP_T*) th)->cb(th, n, (NETAPI_TIMER_LIST_T) &res, ct);
219            tim_return_free(&((TIMER_GROUP_T*) th)->free,&res,n);
220            n_tot+=n;
221       }
222       i += ((TIMER_GROUP_T*) th)->cell_width; 
223       c_seen+=1;
224    }
225    ((TIMER_GROUP_T*) th)->last_polled = i;
226    if (c_seen) timer_poll_stats.n_tot = n_tot;
227    if (c_seen) timer_poll_stats.c_seen = c_seen;
228    if (n_tot > timer_poll_stats.max_n_tot) timer_poll_stats.max_n_tot = n_tot;
229    if (c_seen > timer_poll_stats.max_c_seen) timer_poll_stats.max_c_seen = c_seen;
230    return n_tot;
233 //poll all timers
234 int  netapi_TimerGroupPollAll(NETAPI_T nh, NETAPI_TIMER_FILTER_T f,  int maxTimers)
236  //todo: use filters and poll global, local lists in nh
237  if (temp_g.h)
238     netapi_TimerGroupPoll(&temp_g, maxTimers);
239  return 0;