/* * semscale.cpp - sysv scaling test * * Copyright (C) 1999, 2001, 2005, 2008, 2010 by Manfred Spraul. * All rights reserved except the rights granted by the GPL. * * Redistribution of this file is permitted under the terms of the GNU * General Public License (GPL) version 2 or later. * $Header$ */ #include #include #include #include #include #include #include #include #include #include #ifdef __sun #include /* P_PID, processor_bind() */ #endif #define DELAY_1MS (1000) static enum { WAITING, RUNNING, STOPPED, } volatile g_state = WAITING; int g_svsem_id; pthread_t *g_threads; void* worker_thread(void *arg) { unsigned long long rounds; int ret; rounds = 0; while(g_state == WAITING) { #ifdef __GNUC__ #if defined(__i386__) || defined (__x86_64__) __asm__ __volatile__("pause": : :"memory"); #else __asm__ __volatile__("": : :"memory"); #endif #endif } while(g_state == RUNNING) { struct sembuf sop[1]; struct timespec t; /* 1) check if the semaphore value is 0 */ sop[0].sem_num=0; sop[0].sem_op=0; sop[0].sem_flg=0; t.tv_sec = 0; t.tv_nsec = 1*1000*1000; ret = semtimedop(g_svsem_id,sop,1, &t); if (ret == 0) continue; if (ret == -1 && errno == EAGAIN) continue; if (ret == -1 && errno == EIDRM) break; printf("main semop failed, ret %d errno %d.\n", ret, errno); fflush(stdout); exit(1); } pthread_exit(0); return NULL; } void init_thread(int i) { int ret; ret = pthread_create(&g_threads[i], NULL, worker_thread, NULL); if (ret) { printf(" pthread_create failed with error code %d\n", ret); exit(1); } } ////////////////////////////////////////////////////////////////////////////// static void do_psem(int threads, int secs) { int res; int i; g_state = WAITING; g_threads = (pthread_t*)malloc(sizeof(pthread_t)*threads); g_svsem_id = semget(IPC_PRIVATE,threads,0777|IPC_CREAT); if(g_svsem_id == -1) { printf("sem array create failed.\n"); exit(1); } for (i=0;i