t-sem.c revision 147078
1147078Sgshapiro/* 2147078Sgshapiro * Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers. 3147078Sgshapiro * All rights reserved. 4147078Sgshapiro * 5147078Sgshapiro * By using this file, you agree to the terms and conditions set 6147078Sgshapiro * forth in the LICENSE file which can be found at the top level of 7147078Sgshapiro * the sendmail distribution. 8147078Sgshapiro */ 9147078Sgshapiro 10147078Sgshapiro#include <sm/gen.h> 11147078SgshapiroSM_RCSID("@(#)$Id: t-sem.c,v 1.14 2005/03/25 21:27:41 ca Exp $") 12147078Sgshapiro 13147078Sgshapiro#include <stdio.h> 14147078Sgshapiro 15147078Sgshapiro#if SM_CONF_SEM 16147078Sgshapiro# include <stdlib.h> 17147078Sgshapiro# include <unistd.h> 18147078Sgshapiro# include <sysexits.h> 19147078Sgshapiro# include <sm/heap.h> 20147078Sgshapiro# include <sm/string.h> 21147078Sgshapiro# include <sm/signal.h> 22147078Sgshapiro# include <sm/test.h> 23147078Sgshapiro# include <sm/sem.h> 24147078Sgshapiro 25147078Sgshapirostatic void 26147078Sgshapirodelay(t, s) 27147078Sgshapiro int t; 28147078Sgshapiro char *s; 29147078Sgshapiro{ 30147078Sgshapiro if (t > 0) 31147078Sgshapiro { 32147078Sgshapiro#if DEBUG 33147078Sgshapiro fprintf(stderr, "sleep(%d) before %s\n", t, s); 34147078Sgshapiro#endif /* DEBUG */ 35147078Sgshapiro sleep(t); 36147078Sgshapiro } 37147078Sgshapiro#if DEBUG 38147078Sgshapiro fprintf(stderr, "%s\n", s); 39147078Sgshapiro#endif /* DEBUG */ 40147078Sgshapiro} 41147078Sgshapiro 42147078Sgshapiro 43147078Sgshapiro/* 44147078Sgshapiro** SEMINTER -- interactive testing of semaphores. 45147078Sgshapiro** 46147078Sgshapiro** Parameters: 47147078Sgshapiro** owner -- create semaphores. 48147078Sgshapiro** 49147078Sgshapiro** Returns: 50147078Sgshapiro** 0 on success 51147078Sgshapiro** < 0 on failure. 52147078Sgshapiro*/ 53147078Sgshapiro 54147078Sgshapirostatic int 55147078Sgshapiroseminter(owner) 56147078Sgshapiro bool owner; 57147078Sgshapiro{ 58147078Sgshapiro int semid; 59147078Sgshapiro int t; 60147078Sgshapiro 61147078Sgshapiro semid = sm_sem_start(SM_SEM_KEY, SM_NSEM, 0, owner); 62147078Sgshapiro if (semid < 0) 63147078Sgshapiro { 64147078Sgshapiro perror("sm_sem_start failed"); 65147078Sgshapiro return 1; 66147078Sgshapiro } 67147078Sgshapiro 68147078Sgshapiro while ((t = getchar()) != EOF) 69147078Sgshapiro { 70147078Sgshapiro switch (t) 71147078Sgshapiro { 72147078Sgshapiro case 'a': 73147078Sgshapiro delay(0, "try to acq"); 74147078Sgshapiro if (sm_sem_acq(semid, 0, 2) < 0) 75147078Sgshapiro { 76147078Sgshapiro perror("sm_sem_acq failed"); 77147078Sgshapiro return 1; 78147078Sgshapiro } 79147078Sgshapiro delay(0, "acquired"); 80147078Sgshapiro break; 81147078Sgshapiro 82147078Sgshapiro case 'r': 83147078Sgshapiro delay(0, "try to rel"); 84147078Sgshapiro if (sm_sem_rel(semid, 0, 2) < 0) 85147078Sgshapiro { 86147078Sgshapiro perror("sm_sem_rel failed"); 87147078Sgshapiro return 1; 88147078Sgshapiro } 89147078Sgshapiro delay(0, "released"); 90147078Sgshapiro break; 91147078Sgshapiro 92147078Sgshapiro case 'v': 93147078Sgshapiro if ((t = sm_sem_get(semid, 0)) < 0) 94147078Sgshapiro { 95147078Sgshapiro perror("get_sem failed"); 96147078Sgshapiro return 1; 97147078Sgshapiro } 98147078Sgshapiro printf("semval: %d\n", t); 99147078Sgshapiro break; 100147078Sgshapiro 101147078Sgshapiro } 102147078Sgshapiro } 103147078Sgshapiro if (owner) 104147078Sgshapiro return sm_sem_stop(semid); 105147078Sgshapiro return 0; 106147078Sgshapiro} 107147078Sgshapiro 108147078Sgshapiro/* 109147078Sgshapiro** SEM_CLEANUP -- cleanup if something breaks 110147078Sgshapiro** 111147078Sgshapiro** Parameters: 112147078Sgshapiro** sig -- signal. 113147078Sgshapiro** 114147078Sgshapiro** Returns: 115147078Sgshapiro** none. 116147078Sgshapiro*/ 117147078Sgshapiro 118147078Sgshapirostatic int semid_c = -1; 119147078Sgshapirovoid 120147078Sgshapirosem_cleanup(sig) 121147078Sgshapiro int sig; 122147078Sgshapiro{ 123147078Sgshapiro if (semid_c >= 0) 124147078Sgshapiro (void) sm_sem_stop(semid_c); 125147078Sgshapiro exit(EX_UNAVAILABLE); 126147078Sgshapiro} 127147078Sgshapiro 128147078Sgshapiro/* 129147078Sgshapiro** SEMTEST -- test of semaphores 130147078Sgshapiro** 131147078Sgshapiro** Parameters: 132147078Sgshapiro** owner -- create semaphores. 133147078Sgshapiro** 134147078Sgshapiro** Returns: 135147078Sgshapiro** 0 on success 136147078Sgshapiro** < 0 on failure. 137147078Sgshapiro*/ 138147078Sgshapiro 139147078Sgshapiro# define MAX_CNT 10 140147078Sgshapiro 141147078Sgshapirostatic int 142147078Sgshapirosemtest(owner) 143147078Sgshapiro int owner; 144147078Sgshapiro{ 145147078Sgshapiro int semid, r; 146147078Sgshapiro int cnt = 0; 147147078Sgshapiro 148147078Sgshapiro semid = sm_sem_start(SM_SEM_KEY, 1, 0, owner); 149147078Sgshapiro if (semid < 0) 150147078Sgshapiro { 151147078Sgshapiro perror("sm_sem_start failed"); 152147078Sgshapiro return -1; 153147078Sgshapiro } 154147078Sgshapiro 155147078Sgshapiro if (owner) 156147078Sgshapiro { 157147078Sgshapiro /* just in case someone kills the program... */ 158147078Sgshapiro semid_c = semid; 159147078Sgshapiro (void) sm_signal(SIGHUP, sem_cleanup); 160147078Sgshapiro (void) sm_signal(SIGINT, sem_cleanup); 161147078Sgshapiro (void) sm_signal(SIGTERM, sem_cleanup); 162147078Sgshapiro 163147078Sgshapiro delay(1, "parent: acquire 1"); 164147078Sgshapiro cnt = 0; 165147078Sgshapiro do 166147078Sgshapiro { 167147078Sgshapiro r = sm_sem_acq(semid, 0, 0); 168147078Sgshapiro if (r < 0) 169147078Sgshapiro { 170147078Sgshapiro sleep(1); 171147078Sgshapiro ++cnt; 172147078Sgshapiro } 173147078Sgshapiro } while (r < 0 && cnt <= MAX_CNT); 174147078Sgshapiro SM_TEST(r >= 0); 175147078Sgshapiro if (r < 0) 176147078Sgshapiro return r; 177147078Sgshapiro 178147078Sgshapiro delay(3, "parent: release 1"); 179147078Sgshapiro cnt = 0; 180147078Sgshapiro do 181147078Sgshapiro { 182147078Sgshapiro r = sm_sem_rel(semid, 0, 0); 183147078Sgshapiro if (r < 0) 184147078Sgshapiro { 185147078Sgshapiro sleep(1); 186147078Sgshapiro ++cnt; 187147078Sgshapiro } 188147078Sgshapiro } while (r < 0 && cnt <= MAX_CNT); 189147078Sgshapiro SM_TEST(r >= 0); 190147078Sgshapiro if (r < 0) 191147078Sgshapiro return r; 192147078Sgshapiro 193147078Sgshapiro delay(1, "parent: getval"); 194147078Sgshapiro cnt = 0; 195147078Sgshapiro do 196147078Sgshapiro { 197147078Sgshapiro r = sm_sem_get(semid, 0); 198147078Sgshapiro if (r <= 0) 199147078Sgshapiro { 200147078Sgshapiro sleep(1); 201147078Sgshapiro ++cnt; 202147078Sgshapiro } 203147078Sgshapiro } while (r <= 0 && cnt <= MAX_CNT); 204147078Sgshapiro SM_TEST(r > 0); 205147078Sgshapiro if (r <= 0) 206147078Sgshapiro return r; 207147078Sgshapiro 208147078Sgshapiro delay(1, "parent: acquire 2"); 209147078Sgshapiro cnt = 0; 210147078Sgshapiro do 211147078Sgshapiro { 212147078Sgshapiro r = sm_sem_acq(semid, 0, 0); 213147078Sgshapiro if (r < 0) 214147078Sgshapiro { 215147078Sgshapiro sleep(1); 216147078Sgshapiro ++cnt; 217147078Sgshapiro } 218147078Sgshapiro } while (r < 0 && cnt <= MAX_CNT); 219147078Sgshapiro SM_TEST(r >= 0); 220147078Sgshapiro if (r < 0) 221147078Sgshapiro return r; 222147078Sgshapiro 223147078Sgshapiro cnt = 0; 224147078Sgshapiro do 225147078Sgshapiro { 226147078Sgshapiro r = sm_sem_rel(semid, 0, 0); 227147078Sgshapiro if (r < 0) 228147078Sgshapiro { 229147078Sgshapiro sleep(1); 230147078Sgshapiro ++cnt; 231147078Sgshapiro } 232147078Sgshapiro } while (r < 0 && cnt <= MAX_CNT); 233147078Sgshapiro SM_TEST(r >= 0); 234147078Sgshapiro if (r < 0) 235147078Sgshapiro return r; 236147078Sgshapiro } 237147078Sgshapiro else 238147078Sgshapiro { 239147078Sgshapiro delay(1, "child: acquire 1"); 240147078Sgshapiro cnt = 0; 241147078Sgshapiro do 242147078Sgshapiro { 243147078Sgshapiro r = sm_sem_acq(semid, 0, 0); 244147078Sgshapiro if (r < 0) 245147078Sgshapiro { 246147078Sgshapiro sleep(1); 247147078Sgshapiro ++cnt; 248147078Sgshapiro } 249147078Sgshapiro } while (r < 0 && cnt <= MAX_CNT); 250147078Sgshapiro SM_TEST(r >= 0); 251147078Sgshapiro if (r < 0) 252147078Sgshapiro return r; 253147078Sgshapiro 254147078Sgshapiro delay(1, "child: release 1"); 255147078Sgshapiro cnt = 0; 256147078Sgshapiro do 257147078Sgshapiro { 258147078Sgshapiro r = sm_sem_rel(semid, 0, 0); 259147078Sgshapiro if (r < 0) 260147078Sgshapiro { 261147078Sgshapiro sleep(1); 262147078Sgshapiro ++cnt; 263147078Sgshapiro } 264147078Sgshapiro } while (r < 0 && cnt <= MAX_CNT); 265147078Sgshapiro SM_TEST(r >= 0); 266147078Sgshapiro if (r < 0) 267147078Sgshapiro return r; 268147078Sgshapiro 269147078Sgshapiro } 270147078Sgshapiro if (owner) 271147078Sgshapiro return sm_sem_stop(semid); 272147078Sgshapiro return 0; 273147078Sgshapiro} 274147078Sgshapiro 275147078Sgshapiroint 276147078Sgshapiromain(argc, argv) 277147078Sgshapiro int argc; 278147078Sgshapiro char *argv[]; 279147078Sgshapiro{ 280147078Sgshapiro bool interactive = false; 281147078Sgshapiro bool owner = false; 282147078Sgshapiro int ch; 283147078Sgshapiro int r = 0; 284147078Sgshapiro 285147078Sgshapiro# define OPTIONS "io" 286147078Sgshapiro while ((ch = getopt(argc, argv, OPTIONS)) != -1) 287147078Sgshapiro { 288147078Sgshapiro switch ((char) ch) 289147078Sgshapiro { 290147078Sgshapiro case 'i': 291147078Sgshapiro interactive = true; 292147078Sgshapiro break; 293147078Sgshapiro 294147078Sgshapiro case 'o': 295147078Sgshapiro owner = true; 296147078Sgshapiro break; 297147078Sgshapiro 298147078Sgshapiro default: 299147078Sgshapiro break; 300147078Sgshapiro } 301147078Sgshapiro } 302147078Sgshapiro 303147078Sgshapiro if (interactive) 304147078Sgshapiro r = seminter(owner); 305147078Sgshapiro else 306147078Sgshapiro { 307147078Sgshapiro pid_t pid; 308147078Sgshapiro 309147078Sgshapiro printf("This test takes about 8 seconds.\n"); 310147078Sgshapiro printf("If it takes longer than 30 second, please interrupt it\n"); 311147078Sgshapiro printf("and compile again without semaphore support, i.e.,"); 312147078Sgshapiro printf("-DSM_CONF_SEM=0\n"); 313147078Sgshapiro if ((pid = fork()) < 0) 314147078Sgshapiro { 315147078Sgshapiro perror("fork failed\n"); 316147078Sgshapiro return -1; 317147078Sgshapiro } 318147078Sgshapiro 319147078Sgshapiro sm_test_begin(argc, argv, "test semaphores"); 320147078Sgshapiro if (pid == 0) 321147078Sgshapiro { 322147078Sgshapiro /* give the parent the chance to setup data */ 323147078Sgshapiro sleep(1); 324147078Sgshapiro r = semtest(false); 325147078Sgshapiro } 326147078Sgshapiro else 327147078Sgshapiro { 328147078Sgshapiro r = semtest(true); 329147078Sgshapiro } 330147078Sgshapiro SM_TEST(r == 0); 331147078Sgshapiro return sm_test_end(); 332147078Sgshapiro } 333147078Sgshapiro return r; 334147078Sgshapiro} 335147078Sgshapiro#else /* SM_CONF_SEM */ 336147078Sgshapiroint 337147078Sgshapiromain(argc, argv) 338147078Sgshapiro int argc; 339147078Sgshapiro char *argv[]; 340147078Sgshapiro{ 341147078Sgshapiro printf("No support for semaphores configured on this machine\n"); 342147078Sgshapiro return 0; 343147078Sgshapiro} 344147078Sgshapiro#endif /* SM_CONF_SEM */ 345