1*8a272653SPeter Holm#!/bin/sh 2*8a272653SPeter Holm 3*8a272653SPeter Holm# 4*8a272653SPeter Holm# Copyright (c) 2008 Peter Holm <pho@FreeBSD.org> 5*8a272653SPeter Holm# All rights reserved. 6*8a272653SPeter Holm# 7*8a272653SPeter Holm# Redistribution and use in source and binary forms, with or without 8*8a272653SPeter Holm# modification, are permitted provided that the following conditions 9*8a272653SPeter Holm# are met: 10*8a272653SPeter Holm# 1. Redistributions of source code must retain the above copyright 11*8a272653SPeter Holm# notice, this list of conditions and the following disclaimer. 12*8a272653SPeter Holm# 2. Redistributions in binary form must reproduce the above copyright 13*8a272653SPeter Holm# notice, this list of conditions and the following disclaimer in the 14*8a272653SPeter Holm# documentation and/or other materials provided with the distribution. 15*8a272653SPeter Holm# 16*8a272653SPeter Holm# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17*8a272653SPeter Holm# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18*8a272653SPeter Holm# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19*8a272653SPeter Holm# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20*8a272653SPeter Holm# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21*8a272653SPeter Holm# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22*8a272653SPeter Holm# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23*8a272653SPeter Holm# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24*8a272653SPeter Holm# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25*8a272653SPeter Holm# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26*8a272653SPeter Holm# SUCH DAMAGE. 27*8a272653SPeter Holm# 28*8a272653SPeter Holm 29*8a272653SPeter Holm# panic: spin lock held too long 30*8a272653SPeter Holm 31*8a272653SPeter Holm# Test program and scenario by Peter Wemm <peter@FreeBSD.org> 32*8a272653SPeter Holm 33*8a272653SPeter Holm. ../default.cfg 34*8a272653SPeter Holm 35*8a272653SPeter Holmodir=`pwd` 36*8a272653SPeter Holm 37*8a272653SPeter Holmcd /tmp 38*8a272653SPeter Holmsed '1,/^EOF/d' < $odir/$0 > pth.c 39*8a272653SPeter Holmmycc -o pth -Wall pth.c -pthread 40*8a272653SPeter Holmrm -f pth.c 41*8a272653SPeter Holmcd $odir 42*8a272653SPeter Holm 43*8a272653SPeter Holmfor i in `jot 2000`; do 44*8a272653SPeter Holm /tmp/pth 2>/dev/null 45*8a272653SPeter Holmdone 46*8a272653SPeter Holm 47*8a272653SPeter Holmrm -f /tmp/pth 48*8a272653SPeter Holmexit 49*8a272653SPeter HolmEOF 50*8a272653SPeter Holm#include <pthread.h> 51*8a272653SPeter Holm 52*8a272653SPeter Holm#include <sys/types.h> 53*8a272653SPeter Holm#include <stdlib.h> 54*8a272653SPeter Holm#include <unistd.h> 55*8a272653SPeter Holm#include <string.h> 56*8a272653SPeter Holm#include <stdio.h> 57*8a272653SPeter Holm 58*8a272653SPeter Holmstatic pthread_t worker1_thr; 59*8a272653SPeter Holmstatic pthread_t worker2_thr; 60*8a272653SPeter Holm 61*8a272653SPeter Holmstatic pthread_mutex_t worker_mtx; 62*8a272653SPeter Holmstatic pthread_cond_t worker_go; 63*8a272653SPeter Holmstatic pthread_cond_t worker_done; 64*8a272653SPeter Holm 65*8a272653SPeter Holmstruct workitem { 66*8a272653SPeter Holm struct workitem *next; 67*8a272653SPeter Holm int a, b; 68*8a272653SPeter Holm}; 69*8a272653SPeter Holm 70*8a272653SPeter Holmstruct workitem *head; 71*8a272653SPeter Holm 72*8a272653SPeter Holmstatic void * 73*8a272653SPeter Holmworker(void *arg) 74*8a272653SPeter Holm{ 75*8a272653SPeter Holm struct workitem *w; 76*8a272653SPeter Holm 77*8a272653SPeter Holm pthread_detach(pthread_self()); 78*8a272653SPeter Holm fprintf(stderr, "WORKER: started %p\n", arg); fflush(stderr); 79*8a272653SPeter Holm 80*8a272653SPeter Holm for (;;) { 81*8a272653SPeter Holm pthread_mutex_lock(&worker_mtx); 82*8a272653SPeter Holm while (head == NULL) { 83*8a272653SPeter Holm pthread_cond_wait(&worker_go, &worker_mtx); 84*8a272653SPeter Holm } 85*8a272653SPeter Holm w = head; 86*8a272653SPeter Holm head = w->next; 87*8a272653SPeter Holm pthread_mutex_unlock(&worker_mtx); 88*8a272653SPeter Holm 89*8a272653SPeter Holm fprintf(stderr, "WORKER(%p): got work a=%d b=%d\n", arg, w->a, w->b); fflush(stderr); 90*8a272653SPeter Holm free(w); 91*8a272653SPeter Holm pthread_cond_signal(&worker_done); 92*8a272653SPeter Holm } 93*8a272653SPeter Holm} 94*8a272653SPeter Holm 95*8a272653SPeter Holmvoid 96*8a272653SPeter Holmwork_add(int a, int b) 97*8a272653SPeter Holm{ 98*8a272653SPeter Holm struct workitem *w; 99*8a272653SPeter Holm int dowake = 0; 100*8a272653SPeter Holm 101*8a272653SPeter Holm w = calloc(sizeof(*w), 1); 102*8a272653SPeter Holm w->a = a; 103*8a272653SPeter Holm w->b = b; 104*8a272653SPeter Holm pthread_mutex_lock(&worker_mtx); 105*8a272653SPeter Holm if (head == 0) 106*8a272653SPeter Holm dowake = 1; 107*8a272653SPeter Holm w->next = head; 108*8a272653SPeter Holm head = w; 109*8a272653SPeter Holm pthread_mutex_unlock(&worker_mtx); 110*8a272653SPeter Holm if (dowake) 111*8a272653SPeter Holm pthread_cond_signal(&worker_go); 112*8a272653SPeter Holm} 113*8a272653SPeter Holm 114*8a272653SPeter Holmint 115*8a272653SPeter Holmmain() 116*8a272653SPeter Holm{ 117*8a272653SPeter Holm pthread_mutex_init(&worker_mtx, NULL); 118*8a272653SPeter Holm pthread_cond_init(&worker_go, NULL); 119*8a272653SPeter Holm pthread_cond_init(&worker_done, NULL); 120*8a272653SPeter Holm 121*8a272653SPeter Holm fprintf(stderr, "pthread create\n"); fflush(stderr); 122*8a272653SPeter Holm pthread_create(&worker1_thr, NULL, worker, (void *)1); 123*8a272653SPeter Holm pthread_create(&worker2_thr, NULL, worker, (void *)2); 124*8a272653SPeter Holm 125*8a272653SPeter Holm work_add(10, 15); 126*8a272653SPeter Holm work_add(11, 22); 127*8a272653SPeter Holm work_add(314, 159); 128*8a272653SPeter Holm 129*8a272653SPeter Holm pthread_mutex_lock(&worker_mtx); 130*8a272653SPeter Holm while (head != NULL) { 131*8a272653SPeter Holm pthread_cond_wait(&worker_done, &worker_mtx); 132*8a272653SPeter Holm } 133*8a272653SPeter Holm pthread_mutex_unlock(&worker_mtx); 134*8a272653SPeter Holm 135*8a272653SPeter Holm fprintf(stderr, "job complete\n"); fflush(stderr); 136*8a272653SPeter Holm exit(0); 137*8a272653SPeter Holm} 138