This is the initial commit.
[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,
99         int maxTimers,
100         int *pErr)
102  int ret= tim_group_create(&temp_g, TUNE_NETAPI_NUM_TIMER_CELLS, maxTimers);
103  if (!ret) {*pErr = NETAPI_ERR_NOMEM; return NULL;}
104  *pErr=0;
105  temp_g.cb = cb;
106  temp_g.local = local;
107  temp_g.exp2cancel= exp2cancel;
108  temp_g.cell_width=cell_width;
109  temp_g.h = netHandle;
110  temp_g.last_polled=(netapi_getTimestamp()/cell_width) * cell_width + (cell_width-1);
111  printf(">timer group %s created. width = %d (ticks)\n", name, cell_width);
112  return (NETAPI_TIMER_GROUP_HANDLE_T) &temp_g;
115 //open a [global] timer group
116 NETAPI_TIMER_GROUP_HANDLE_T  netapi_TimerGroupOpen(
117         NETAPI_T netHandle,
118         NETAPI_TIMER_CB_T cb,
119         int *pErr)
121 printf(">timer group open not implemented \n");
125 //start an individual timer
126 NETAPI_TIMER_T netapi_TimerGroupStartTimer(
127         NETAPI_TIMER_GROUP_HANDLE_T th,
128         void * cookie,
129         uint64_t offs2fire,  //offset in group ticks 
130         int * pErr)
132 TIM_T * timer_obj;
133 unsigned long long ct= netapi_getTimestamp() + offs2fire* ((TIMER_GROUP_T*) th)->cell_width;
134 int cell;
135 *pErr=0;
137 //find cell where to insert
138 cell = our_hash(ct,((TIMER_GROUP_T*) th)->n_cells , ((TIMER_GROUP_T*) th)->cell_width);
140 //get object and insert into this cell
141 timer_obj =tim_set(
142    &((TIMER_GROUP_T*) th)->cells[cell],
143    &((TIMER_GROUP_T*) th)->free , 
144    ct,
145    cookie,
146    pErr);
147 if (!timer_obj)  {return NULL;}
148 printf(">timer: setting timer %x for %lld ticks -> hased to cell %d\n",cookie, ct,cell);
149 return (NETAPI_TIMER_T) timer_obj;
152 //Cancel a timer
153 void  netapi_TimerGroupCancel(
154         NETAPI_TIMER_GROUP_HANDLE_T th,
155         NETAPI_TIMER_T timerId,
156         int *pErr)
158     tim_cancel((TIM_T *) timerId, pErr);
161 //close an opened timer group
162 void netapi_TimerGroupClose(
163         NETAPI_TIMER_GROUP_HANDLE_T th,
164         int *pErr){}
166 //delete atimer group
167 void netapi_TimerGroupDelete(
168         NETAPI_TIMER_GROUP_HANDLE_T th,
169         int *pErr) {printf(">timer group delete not implemented\n");}
171 //extract netapi handle from timer group handle
172 NETAPI_T netap_TimerGroupGetNH( NETAPI_TIMER_GROUP_HANDLE_T th) { return ((TIMER_GROUP_T*) th)->h; }
175 //-----for timer debuggingi-------
176 struct
178 //last poll stats
179 int n_tot;
180 int c_seen;
182 int max_c_seen;
183 int max_n_tot;
185 } timer_poll_stats;
186 void dump_poll_stats(void)
188   printf("debug timer poll> n_tot=%d c_seen=%d mnt=%d mcs=%d\n",
189              timer_poll_stats.n_tot, timer_poll_stats.c_seen,
190              timer_poll_stats.max_n_tot, timer_poll_stats.max_c_seen);
192 //-------end timer debugging----
194 //poll a specific timer group
195 int  netapi_TimerGroupPoll(NETAPI_TIMER_GROUP_HANDLE_T th, int maxTimers)
197 unsigned long long ct= netapi_getTimestamp(); 
198 unsigned long long i;
199 int cell;
200 TIM_LIST_T res;
201 int n;
202 int n_tot=0;
203 int c_seen=0;
205    for(i=((TIMER_GROUP_T*) th)->last_polled; (i<= ct) && (n_tot<maxTimers); )
206    {
207       cell =  our_hash(i,((TIMER_GROUP_T*) th)->n_cells , ((TIMER_GROUP_T*) th)->cell_width); 
208       tim_return_fired_list(&((TIMER_GROUP_T*) th)->cells[cell],
209                             &res,
210                             &((TIMER_GROUP_T*) th)->free,
211                             i,
212                             &n);
213       if (n)
214       {
215            ((TIMER_GROUP_T*) th)->cb(th, n, (NETAPI_TIMER_LIST_T) &res, ct);
216            tim_return_free(&((TIMER_GROUP_T*) th)->free,&res,n);
217            n_tot+=n;
218       }
219       i += ((TIMER_GROUP_T*) th)->cell_width; 
220       c_seen+=1;
221    }
222    ((TIMER_GROUP_T*) th)->last_polled = i;
223    timer_poll_stats.n_tot = n_tot;
224    timer_poll_stats.c_seen = c_seen;
225    if (n_tot > timer_poll_stats.max_n_tot) timer_poll_stats.max_n_tot = n_tot;
226    if (c_seen > timer_poll_stats.max_c_seen) timer_poll_stats.max_c_seen = c_seen;
227    return n_tot;
230 //poll all timers
231 int  netapi_TimerGroupPollAll(NETAPI_T nh, NETAPI_TIMER_FILTER_T f,  int maxTimers)
233  //todo: use filters and poll global, local lists in nh
234  netapi_TimerGroupPoll(&temp_g, maxTimers);
235  return 0;