/* * File : lf_fifo_test.c * Author : Jérémy Zurcher * Date : 2013/01/30 * License : * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ #include "stdio.h" #include "stdlib.h" #include #include "lf_fifo.h" typedef struct _node_t { uint32_t data; lf_pointer_t link; } node_t; typedef struct _thread_params_t { uint32_t n; lf_fifo_t *fifo; node_t *nodes; } thread_params_t; static void _failure(const char *msg) { fprintf(stderr,"%s\n",msg); exit(EXIT_FAILURE); } static void _check(int cond, const char *msg) { if(!cond) { fprintf(stderr,"%s\n",msg); exit(EXIT_FAILURE); } } static uint64_t time_diff(struct timespec *t0, struct timespec *t1) { return ((t1->tv_sec * 1000000000) + t1->tv_nsec) - ((t0->tv_sec * 1000000000) + t0->tv_nsec); } static void report( char* op, uint32_t threads, uint32_t nodes, uint64_t dt) { uint32_t n = threads*nodes; fprintf(stdout," - %s: %3d threads * %6d op in %4u [ms] : %7u [us] : %10u [ns]\t -> %6d [ns/op]\n", op, threads, nodes, (unsigned int)(dt/1000000), (unsigned int)(dt/1000), (unsigned int)dt, (int)(dt/n)); } static uint32_t fifo_length(lf_fifo_t *fifo) { uint32_t l = 0; lf_pointer_t* link; link = (lf_pointer_t*)fifo->head.pointer; while(link) { l++; link = (lf_pointer_t*)link->pointer; } return l; } void* aggressive_push( void* param ) { uint32_t i; lf_fifo_t *fifo; node_t *nodes; thread_params_t *params; params = (thread_params_t*)param; fifo = params->fifo; nodes = params->nodes = malloc( sizeof(node_t)*params->n); if (nodes==NULL) _failure("nodes malloc failure"); for(i=0; in; i++) { nodes[i].data = i+1; lf_fifo_push(fifo,&nodes[i].link); } params->n = i; return NULL; } void* aggressive_pop( void* param ) { uint32_t i; lf_fifo_t *fifo; thread_params_t *params; params = (thread_params_t*)param; fifo = params->fifo; i = 0; for(;;) { if(lf_fifo_pop(fifo)==NULL) break; i++; } params->n = i; return NULL; } static void run_aggressive_push_pop(int threads_n, int nodes_n) { uint32_t i, j; lf_fifo_t fifo; pthread_t *threads; thread_params_t *params; struct timespec start, end; threads = malloc( sizeof(pthread_t)*threads_n); if (threads==NULL) _failure("threads malloc failure"); params = malloc( sizeof(thread_params_t)*threads_n); if (params==NULL) _failure("params malloc failure"); lf_fifo_init( &fifo); for(i=0; i