1/*** 2 This file is part of PulseAudio. 3 4 PulseAudio is free software; you can redistribute it and/or modify 5 it under the terms of the GNU Lesser General Public License as published 6 by the Free Software Foundation; either version 2.1 of the License, 7 or (at your option) any later version. 8 9 PulseAudio is distributed in the hope that it will be useful, but 10 WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 General Public License for more details. 13 14 You should have received a copy of the GNU Lesser General Public License 15 along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. 16***/ 17 18#ifdef HAVE_CONFIG_H 19#include <config.h> 20#endif 21 22#include <stdio.h> 23#include <unistd.h> 24 25#include <check.h> 26 27#include <pulse/xmalloc.h> 28 29#include <pulsecore/log.h> 30#include <pulsecore/memblock.h> 31#include <pulsecore/macro.h> 32 33static void release_cb(pa_memimport *i, uint32_t block_id, void *userdata) { 34 pa_log("%s: Imported block %u is released.", (char*) userdata, block_id); 35} 36 37static void revoke_cb(pa_memexport *e, uint32_t block_id, void *userdata) { 38 pa_log("%s: Exported block %u is revoked.", (char*) userdata, block_id); 39} 40 41static void print_stats(pa_mempool *p, const char *text) { 42 const pa_mempool_stat*s = pa_mempool_get_stat(p); 43 44 pa_log_debug("%s = {\n" 45 "\tn_allocated = %u\n" 46 "\tn_accumulated = %u\n" 47 "\tn_imported = %u\n" 48 "\tn_exported = %u\n" 49 "\tallocated_size = %u\n" 50 "\taccumulated_size = %u\n" 51 "\timported_size = %u\n" 52 "\texported_size = %u\n" 53 "\tn_too_large_for_pool = %u\n" 54 "\tn_pool_full = %u\n" 55 "}", 56 text, 57 (unsigned) pa_atomic_load(&s->n_allocated), 58 (unsigned) pa_atomic_load(&s->n_accumulated), 59 (unsigned) pa_atomic_load(&s->n_imported), 60 (unsigned) pa_atomic_load(&s->n_exported), 61 (unsigned) pa_atomic_load(&s->allocated_size), 62 (unsigned) pa_atomic_load(&s->accumulated_size), 63 (unsigned) pa_atomic_load(&s->imported_size), 64 (unsigned) pa_atomic_load(&s->exported_size), 65 (unsigned) pa_atomic_load(&s->n_too_large_for_pool), 66 (unsigned) pa_atomic_load(&s->n_pool_full)); 67} 68 69START_TEST (memblock_test) { 70 pa_mempool *pool_a, *pool_b, *pool_c; 71 unsigned id_a, id_b, id_c; 72 pa_memexport *export_a, *export_b; 73 pa_memimport *import_b, *import_c; 74 pa_memblock *mb_a, *mb_b, *mb_c; 75 int r, i; 76 pa_memblock* blocks[5]; 77 pa_mem_type_t mem_type; 78 uint32_t id, shm_id; 79 size_t offset, size; 80 char *x; 81 82 const char txt[] = "This is a test!"; 83 84 pool_a = pa_mempool_new(PA_MEM_TYPE_SHARED_POSIX, 0, true); 85 fail_unless(pool_a != NULL); 86 pool_b = pa_mempool_new(PA_MEM_TYPE_SHARED_POSIX, 0, true); 87 fail_unless(pool_b != NULL); 88 pool_c = pa_mempool_new(PA_MEM_TYPE_SHARED_POSIX, 0, true); 89 fail_unless(pool_c != NULL); 90 91 pa_mempool_get_shm_id(pool_a, &id_a); 92 pa_mempool_get_shm_id(pool_b, &id_b); 93 pa_mempool_get_shm_id(pool_c, &id_c); 94 95 blocks[0] = pa_memblock_new_fixed(pool_a, (void*) txt, sizeof(txt), 1); 96 97 blocks[1] = pa_memblock_new(pool_a, sizeof(txt)); 98 x = pa_memblock_acquire(blocks[1]); 99 snprintf(x, pa_memblock_get_length(blocks[1]), "%s", txt); 100 pa_memblock_release(blocks[1]); 101 102 blocks[2] = pa_memblock_new_pool(pool_a, sizeof(txt)); 103 x = pa_memblock_acquire(blocks[2]); 104 snprintf(x, pa_memblock_get_length(blocks[2]), "%s", txt); 105 pa_memblock_release(blocks[2]); 106 107 blocks[3] = pa_memblock_new_malloced(pool_a, pa_xstrdup(txt), sizeof(txt)); 108 blocks[4] = NULL; 109 110 for (i = 0; blocks[i]; i++) { 111 pa_log("Memory block %u", i); 112 113 mb_a = blocks[i]; 114 fail_unless(mb_a != NULL); 115 116 export_a = pa_memexport_new(pool_a, revoke_cb, (void*) "A"); 117 fail_unless(export_a != NULL); 118 export_b = pa_memexport_new(pool_b, revoke_cb, (void*) "B"); 119 fail_unless(export_b != NULL); 120 121 import_b = pa_memimport_new(pool_b, release_cb, (void*) "B"); 122 fail_unless(import_b != NULL); 123 import_c = pa_memimport_new(pool_c, release_cb, (void*) "C"); 124 fail_unless(import_b != NULL); 125 126 r = pa_memexport_put(export_a, mb_a, &mem_type, &id, &shm_id, &offset, &size); 127 fail_unless(r >= 0); 128 fail_unless(shm_id == id_a); 129 130 pa_log("A: Memory block exported as %u", id); 131 132 mb_b = pa_memimport_get(import_b, PA_MEM_TYPE_SHARED_POSIX, id, shm_id, offset, size, false); 133 fail_unless(mb_b != NULL); 134 r = pa_memexport_put(export_b, mb_b, &mem_type, &id, &shm_id, &offset, &size); 135 fail_unless(r >= 0); 136 fail_unless(shm_id == id_a || shm_id == id_b); 137 pa_memblock_unref(mb_b); 138 139 pa_log("B: Memory block exported as %u", id); 140 141 mb_c = pa_memimport_get(import_c, PA_MEM_TYPE_SHARED_POSIX, id, shm_id, offset, size, false); 142 fail_unless(mb_c != NULL); 143 x = pa_memblock_acquire(mb_c); 144 pa_log_debug("1 data=%s", x); 145 pa_memblock_release(mb_c); 146 147 print_stats(pool_a, "A"); 148 print_stats(pool_b, "B"); 149 print_stats(pool_c, "C"); 150 151 pa_memexport_free(export_b); 152 x = pa_memblock_acquire(mb_c); 153 pa_log_debug("2 data=%s", x); 154 pa_memblock_release(mb_c); 155 pa_memblock_unref(mb_c); 156 157 pa_memimport_free(import_b); 158 159 pa_memblock_unref(mb_a); 160 161 pa_memimport_free(import_c); 162 pa_memexport_free(export_a); 163 } 164 165 pa_log("vacuuming..."); 166 167 pa_mempool_vacuum(pool_a); 168 pa_mempool_vacuum(pool_b); 169 pa_mempool_vacuum(pool_c); 170 171 pa_log("vacuuming done..."); 172 173 pa_mempool_unref(pool_a); 174 pa_mempool_unref(pool_b); 175 pa_mempool_unref(pool_c); 176} 177END_TEST 178 179int main(int argc, char *argv[]) { 180 int failed = 0; 181 Suite *s; 182 TCase *tc; 183 SRunner *sr; 184 185 if (!getenv("MAKE_CHECK")) 186 pa_log_set_level(PA_LOG_DEBUG); 187 188 s = suite_create("Memblock"); 189 tc = tcase_create("memblock"); 190 tcase_add_test(tc, memblock_test); 191 suite_add_tcase(s, tc); 192 193 sr = srunner_create(s); 194 srunner_run_all(sr, CK_NORMAL); 195 failed = srunner_ntests_failed(sr); 196 srunner_free(sr); 197 198 return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; 199} 200