/**************************************** * File: netapi_sched.c * Purpose: netapi scheduling module * NOTE: This sample right now. ************************************************************** * FILE: netapi_sched.c * * DESCRIPTION: netapi sample scheduler source file for user space transport * library * * REVISION HISTORY: rev 0.0.1 * * Copyright (c) Texas Instruments Incorporated 2010-2011 * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ****************************************/ #include "netapi.h" #include "netapi_sched.h" #define NO_TIMER //turn off timer related scheduling /******************************************************************** * FUNCTION PURPOSE: API to get scheduling context statistics ******************************************************************** * DESCRIPTION: API to get scheduling context statistics ********************************************************************/ void netapi_schedGetStats(NETAPI_SCHED_HANDLE_T *s, unsigned long long * p_pkts, unsigned long long * p_cycles, unsigned long long * p_cache_cycles) { *p_pkts= s->stats.num_pkts; *p_cycles= s->stats.busy_cycles; *p_cache_cycles= s->stats.cache_cycles; return; } /****************************************/ /************API************************/ /**************************************/ /******************************************************************** * FUNCTION PURPOSE: API to open a scheduling context ******************************************************************** * DESCRIPTION: API to open a scheduling context ********************************************************************/ NETAPI_SCHED_HANDLE_T * netapi_schedOpen(NETAPI_T n, NETAPI_SCHED_CONFIG_T * p_config, int *p_err) { *p_err=0; NETAPI_SCHED_HANDLE_T * ph = (NETAPI_SCHED_HANDLE_T *) netapi_get_scheduler(n); if(!ph) {*p_err= NETAPI_ERR_NOMEM; return NULL;} if(!p_config) {*p_err= NETAPI_ERR_BAD_INPUT; return NULL;} memcpy(&ph->config,p_config,sizeof(NETAPI_SCHED_CONFIG_T)); ph->start = hplib_mUtilGetTimestamp(); ph->back = (void *) n; if (ph->config.valid_flags & NETAPI_SCHED_DURATION) { if (ph->config.duration == NETAPI_SCHED_FOREVER) { ph->shutdown_time=(uint64_t) -1; } else { ph->shutdown_time = ph->start + ph->config.duration; } } else ph->shutdown_time = (uint64_t) -1; ph->state =NETAPI_SCHED_STATE_OPEN; return(ph); } /******************************************************************** * FUNCTION PURPOSE: API to re-configure a scheduling context, FUTURE, * not implemented ******************************************************************** * DESCRIPTION: API to re-configure a scheduling context, FUTURE, * not implemented ********************************************************************/ int netapi_schedControl(NETAPI_SCHED_HANDLE_T *s, NETAPI_SCHED_CONFIG_T *p_config, int *p_err) { /* NOT_IMPLEMENTED */ return 0; } /******************************************************************** * FUNCTION PURPOSE: API for main entry point to scheduler ******************************************************************** * DESCRIPTION: API to get NETAPI scheduling context statistics ********************************************************************/ /* main entry point. caller gives up control to scheduler */ int netapi_schedRun(NETAPI_SCHED_HANDLE_T *s, int *p_err) { int err; *p_err=0; unsigned long long t = hplib_mUtilGetTimestamp(); int next_house; volatile int pkts; volatile unsigned long t1; volatile unsigned long t2; volatile unsigned long long cache_op_b2; volatile unsigned long long n_c_ops; next_house = s->config.interval; /* loop for duration or until shutdown */ for(;t< s->shutdown_time;) { #ifndef NO_TIMER t = hplib_mUtilGetTimestamp(); #endif next_house -=1; //poll all pktio channels we have open in RX mode //Osal_cache_op_measure_reset(); cache_op_b2= Osal_cache_op_measure(&n_c_ops); t1=hplib_mUtilGetPmuCCNT(); pkts=pktio_pollAll((NETAPI_T) s->back, NULL, &err); if (!pkts && (s->config.yield == TRUE)) { sched_yield(); } t2=hplib_mUtilGetPmuCCNT(); if (pkts) { s->stats.num_pkts+= (unsigned long long) pkts; s->stats.busy_cycles += (unsigned long long) (t2-t1); cache_op_b2= Osal_cache_op_measure(&n_c_ops)- cache_op_b2; s->stats.cache_cycles += (unsigned long long) cache_op_b2; } //poll pktlib garbage collections for registered heaps if (TRUE == s->config.pollGarbageQ) { netapi_pollHeapGarbage((NETAPI_T) s->back); } //poll NETCP/PA control channels if (TRUE == s->config.pollCtrlQ) { netapi_netcpPoll((NETAPI_T) s->back); } //see if time to do a house keeping callback if ((s->config.valid_flags & NETAPI_SCHED_CBV) && s->config.house_cb) if (next_house<=0) { s->config.house_cb(s); next_house = s->config.interval; } //see if we were closed and/or its time to close if (s->state!= NETAPI_SCHED_STATE_OPEN) { s->state=NETAPI_SCHED_STATE_CLOSE; break; } } return 1; } /******************************************************************** * FUNCTION PURPOSE: API to close a scheduling context ******************************************************************** * DESCRIPTION: API to close a scheduling context ********************************************************************/ /* shutdown scheduler context */ int netapi_schedClose(NETAPI_SCHED_HANDLE_T * s, NETAPI_SCHED_SHUTDOWN_T * p_close, int * p_err) { *p_err=0; if (p_close->shutdown_type == NETAPI_SCHED_SHUTDOWN_NOW) { s->state=NETAPI_SCHED_STATE_CLOSE_IN_PROGRESS; //say we are closing } return 1; }