1/********************************************************************* 2 PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 Do not redistribute without a written permission by the Copyright 5 holders. 6 *********************************************************************/ 7 8 9/* This is a test implementation, with a faulty memory manager, 10 * intended to increase test coverage 11 * Warning: not intended for production! 12 * 13 */ 14 15 16#ifndef PICO_SUPPORT_POSIX 17#define PICO_SUPPORT_POSIX 18 19#define PICO_FAULTY 20 21#define MEM_LIMIT (0) 22 23#include <string.h> 24#include <stdio.h> 25#include <unistd.h> 26#include <sys/time.h> 27#include <fcntl.h> 28#include <stdlib.h> 29 30extern uint32_t mm_failure_count; 31int pico_set_mm_failure(uint32_t nxt); 32extern uint32_t max_mem; 33extern uint32_t cur_mem; 34 35/* 36 #define TIME_PRESCALE 37 */ 38#define dbg printf 39 40#define stack_fill_pattern(...) do {} while(0) 41#define stack_count_free_words(...) do {} while(0) 42#define stack_get_free_words() (0) 43 44static inline void mem_stat_store(void) 45{ 46 char fname_mod[] = "/tmp/pico-mem-report-%hu.txt"; 47 char fname[200]; 48 char buffer[20]; 49 int fd; 50 snprintf(fname, 200, fname_mod, getpid()); 51 fd = open(fname, O_WRONLY | O_CREAT | O_TRUNC, 0660); 52 if (fd < 0) { 53 return; 54 } 55 56 snprintf(buffer, 20, "%d\n", max_mem); 57 write(fd, buffer, strlen(buffer)); 58 close(fd); 59} 60 61 62static inline void *pico_zalloc(size_t x) 63{ 64 uint32_t *ptr; 65 if (mm_failure_count > 0) { 66 if (--mm_failure_count == 0) { 67 fprintf(stderr, "Malloc failed, for test purposes\n"); 68 return NULL; 69 } 70 } 71 72 ptr = (uint32_t *)calloc(x + sizeof(uint32_t), 1); 73 *ptr = (uint32_t)x; /* store size of alloc */ 74 cur_mem += (uint32_t)x; 75 76#ifndef DISABLE_MM_STATS 77 if (cur_mem > max_mem) { 78 max_mem = cur_mem; 79 if ((MEM_LIMIT > 0) && (max_mem > MEM_LIMIT)) 80 abort(); 81 82 mem_stat_store(); 83 } 84 85#endif 86 return (void*)(ptr + 1); 87} 88 89static inline void pico_free(void *x) 90{ 91 uint32_t *ptr = (uint32_t*)(((uint8_t *)x) - sizeof(uint32_t)); /* fetch size of the alloc */ 92 cur_mem -= *ptr; 93 free(ptr); 94} 95 96/* time prescaler */ 97#ifdef TIME_PRESCALE 98extern int32_t prescale_time; 99#endif 100 101static inline uint32_t PICO_TIME(void) 102{ 103 struct timeval t; 104 gettimeofday(&t, NULL); 105 #ifdef TIME_PRESCALE 106 return (prescale_time < 0) ? (uint32_t)(t.tv_sec / 1000 << (-prescale_time)) : \ 107 (uint32_t)(t.tv_sec / 1000 >> prescale_time); 108 #else 109 return (uint32_t)t.tv_sec; 110 #endif 111} 112 113static inline uint32_t PICO_TIME_MS(void) 114{ 115 struct timeval t; 116 gettimeofday(&t, NULL); 117 #ifdef TIME_PRESCALER 118 uint32_t tmp = ((t.tv_sec * 1000) + (t.tv_usec / 1000)); 119 return (prescale_time < 0) ? (uint32_t)(tmp / 1000 << (-prescale_time)) : \ 120 (uint32_t)(tmp / 1000 >> prescale_time); 121 #else 122 return (uint32_t)((t.tv_sec * 1000) + (t.tv_usec / 1000)); 123 #endif 124} 125 126static inline void PICO_IDLE(void) 127{ 128 usleep(5000); 129} 130 131void memory_stats(void); 132 133#endif /* PICO_SUPPORT_POSIX */ 134 135