1 /****************************************
2 * File: netapi_sched.c
3 * Purpose: netapi scheduling module
4 * NOTE: This sample right now.
5 **************************************************************
6 * FILE: netapi_sched.c
7 *
8 * DESCRIPTION: netapi sample scheduler source file for user space transport
9 * library
10 *
11 * REVISION HISTORY:
12 *
13 * Copyright (c) Texas Instruments Incorporated 2013
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 *
19 * Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 *
22 * Redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the
25 * distribution.
26 *
27 * Neither the name of Texas Instruments Incorporated nor the names of
28 * its contributors may be used to endorse or promote products derived
29 * from this software without specific prior written permission.
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.
43 ****************************************/
45 #include "netapi_sched.h"
47 #define NO_TIMER //turn off timer related scheduling
50 /********************************************************************
51 * FUNCTION PURPOSE: API to get scheduling context statistics
52 ********************************************************************
53 * DESCRIPTION: API to get scheduling context statistics
54 ********************************************************************/
55 void netapi_schedGetStats(NETAPI_SCHED_HANDLE_T *s,
56 unsigned long long * p_pkts,
57 unsigned long long * p_cycles,
58 unsigned long long * p_cache_cycles)
59 {
60 *p_pkts= s->stats.num_pkts;
61 *p_cycles= s->stats.busy_cycles;
62 *p_cache_cycles= s->stats.cache_cycles;
63 return;
64 }
65 /****************************************/
66 /************API************************/
67 /**************************************/
69 /********************************************************************
70 * FUNCTION PURPOSE: API to open a scheduling context
71 ********************************************************************
72 * DESCRIPTION: API to open a scheduling context
73 ********************************************************************/
74 NETAPI_SCHED_HANDLE_T * netapi_schedOpen(NETAPI_T n,
75 NETAPI_SCHED_CONFIG_T * p_config,
76 int *p_err)
77 {
78 *p_err=0;
79 NETAPI_SCHED_HANDLE_T * ph = (NETAPI_SCHED_HANDLE_T *) netapi_get_scheduler(n);
80 if(!ph)
81 {
82 *p_err= NETAPI_ERR_NOMEM;
83 return NULL;
84 }
85 if(!p_config)
86 {
87 *p_err= NETAPI_ERR_BAD_INPUT;
88 return NULL;
89 }
90 memcpy(&ph->config,p_config,sizeof(NETAPI_SCHED_CONFIG_T));
91 ph->start = hplib_mUtilGetTimestamp();
92 ph->back = (void *) n;
93 if (ph->config.valid_flags & NETAPI_SCHED_DURATION)
94 {
95 if (ph->config.duration == NETAPI_SCHED_FOREVER)
96 {
97 ph->shutdown_time=(uint64_t) -1;
98 }
99 else
100 {
101 ph->shutdown_time = ph->start + ph->config.duration;
102 }
103 }
104 else
105 {
106 ph->shutdown_time = (uint64_t) -1;
107 }
108 ph->state =NETAPI_SCHED_STATE_OPEN;
109 return(ph);
110 }
112 /********************************************************************
113 * FUNCTION PURPOSE: API to re-configure a scheduling context, FUTURE,
114 * not implemented
115 ********************************************************************
116 * DESCRIPTION: API to re-configure a scheduling context, FUTURE,
117 * not implemented
118 ********************************************************************/
120 int netapi_schedControl(NETAPI_SCHED_HANDLE_T *s,
121 NETAPI_SCHED_CONFIG_T *p_config,
122 int *p_err)
123 {
124 /* NOT_IMPLEMENTED */
125 return 0;
126 }
128 /********************************************************************
129 * FUNCTION PURPOSE: API for main entry point to scheduler
130 ********************************************************************
131 * DESCRIPTION: API to get NETAPI scheduling context statistics
132 ********************************************************************/
133 /* main entry point. caller gives up control to scheduler */
134 int netapi_schedRun(NETAPI_SCHED_HANDLE_T *s,
135 int *p_err)
136 {
137 int err;
138 *p_err=0;
139 unsigned long long t = hplib_mUtilGetTimestamp();
140 int next_house;
141 volatile int pkts;
142 volatile unsigned long t1;
143 volatile unsigned long t2;
144 volatile unsigned long long cache_op_b2;
145 volatile unsigned long long n_c_ops;
147 next_house = s->config.interval;
148 /* loop for duration or until shutdown */
149 for(;t< s->shutdown_time;)
150 {
151 #ifndef NO_TIMER
152 t = hplib_mUtilGetTimestamp();
153 #endif
154 next_house -=1;
156 cache_op_b2= Osal_cache_op_measure(&n_c_ops);
157 t1=hplib_mUtilGetPmuCCNT();
158 /* poll all pktio channels we have open in RX mode */
159 pkts=netapi_pktioPollAll((NETAPI_T) s->back, NULL, &err);
160 if (!pkts && (s->config.yield == NETAPI_TRUE))
161 {
162 sched_yield();
163 }
164 t2=hplib_mUtilGetPmuCCNT();
165 if (pkts)
166 {
167 s->stats.num_pkts+= (unsigned long long) pkts;
168 s->stats.busy_cycles += (unsigned long long) (t2-t1);
169 cache_op_b2= Osal_cache_op_measure(&n_c_ops)- cache_op_b2;
170 s->stats.cache_cycles += (unsigned long long) cache_op_b2;
171 }
173 /* poll pktlib garbage collections for registered heaps */
174 if (NETAPI_TRUE == s->config.pollGarbageQ)
175 {
176 netapi_pollHeapGarbage((NETAPI_T) s->back);
177 }
180 /*poll NETCP/PA control channels */
181 if (NETAPI_TRUE == s->config.pollCtrlQ)
182 {
183 netapi_netcpPoll((NETAPI_T) s->back);
184 }
186 /* see if time to do a house keeping callback */
187 if ((s->config.valid_flags & NETAPI_SCHED_CBV) && s->config.house_cb)
188 if (next_house<=0)
189 {
190 s->config.house_cb(s);
191 next_house = s->config.interval;
192 }
193 /* see if we were closed and/or its time to close */
194 if (s->state!= NETAPI_SCHED_STATE_OPEN)
195 {
196 s->state=NETAPI_SCHED_STATE_CLOSE;
197 break;
198 }
200 }
201 return 1;
202 }
203 /********************************************************************
204 * FUNCTION PURPOSE: API to close a scheduling context
205 ********************************************************************
206 * DESCRIPTION: API to close a scheduling context
207 ********************************************************************/
208 /* shutdown scheduler context */
209 int netapi_schedClose(NETAPI_SCHED_HANDLE_T * s,
210 NETAPI_SCHED_SHUTDOWN_T * p_close,
211 int * p_err)
212 {
213 *p_err=0;
214 if (p_close->shutdown_type == NETAPI_SCHED_SHUTDOWN_NOW)
215 {
216 s->state=NETAPI_SCHED_STATE_CLOSE_IN_PROGRESS;
217 }
218 return 1;
219 }