pthread_tad.c
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:5k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* ==== pthread_tad.c =========================================================
  2.  * Copyright (c) 1995 by Chris Provenzano, proven@athena.mit.edu
  3.  *
  4.  * Redistribution and use in source and binary forms, with or without
  5.  * modification, are permitted provided that the following conditions
  6.  * are met:
  7.  * 1. Redistributions of source code must retain the above copyright
  8.  *    notice, this list of conditions and the following disclaimer.
  9.  * 2. Redistributions in binary form must reproduce the above copyright
  10.  *    notice, this list of conditions and the following disclaimer in the
  11.  *    documentation and/or other materials provided with the distribution.
  12.  * 3. All advertising materials mentioning features or use of this software
  13.  *    must display the following acknowledgement:
  14.  * This product includes software developed by Chris Provenzano,
  15.  * and its contributors.
  16.  * 4. Neither the name of Chris Provenzano, nor the names of
  17.  *   its contributors may be used to endorse or promote products derived
  18.  *    from this software without specific prior written permission.
  19.  *
  20.  * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO, AND CONTRIBUTORS
  21.  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  22.  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  23.  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
  24.  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  25.  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  26.  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  27.  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  28.  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  29.  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  30.  * POSSIBILITY OF SUCH DAMAGE.
  31.  *
  32.  */
  33. #ifndef lint
  34. static char copyright[] =
  35.  "@(#) Copyright (c) 1995 Chris Provenzano.nAll rights reserved.n";
  36. #endif /* not lint */
  37. /* tad = thread allocation domain */
  38. #define PTHREAD_KERNEL
  39. #include "pthreadutil.h"
  40. #include <stdio.h>
  41. #include <errno.h>
  42. int pthread_tad_count(pthread_tad_t * tad)
  43. {
  44. int ret;
  45. pthread_mutex_lock(&tad->mutex);
  46. ret = tad->count_current;
  47. pthread_mutex_unlock(&tad->mutex);
  48. return(ret);
  49. }
  50. static void pthread_tad_done(void * arg)
  51. {
  52. pthread_tad_t * tad = arg;
  53. pthread_mutex_lock(&tad->mutex);
  54. --tad->count_current;
  55. /* if (--tad->count_current < tad->count_max) */
  56. pthread_cond_broadcast(&tad->cond);
  57. pthread_mutex_unlock(&tad->mutex);
  58. }
  59. #ifndef PTHREAD_KERNEL
  60. struct tad_start {
  61. pthread_tad_t * tad;
  62. void * (*routine)();
  63. void * arg;
  64. };
  65. static void * pthread_tad_start(struct tad_start * tad_start)
  66. {
  67. void * (*routine)() = tad_start->routine;
  68. void * arg = tad_start->arg;
  69. pthread_mutex_lock(&tad_start->tad->mutex);
  70. pthread_cleanup_push(pthread_tad_done, tad_start->tad);
  71. pthread_mutex_unlock(&tad_start->tad->mutex);
  72. free(tad_start);
  73. return(routine(arg));
  74. }
  75. #else
  76. static void * pthread_tad_start(void * tad_start_arg)
  77. {
  78. pthread_tad_t * tad = tad_start_arg;
  79. void * (*routine)() = tad->routine;
  80. void * arg = tad->arg;
  81. tad->count_current++;
  82. pthread_cleanup_push(pthread_tad_done, tad);
  83. pthread_mutex_unlock(&tad->mutex);
  84. return(routine(arg));
  85. }
  86. #endif
  87. int pthread_tad_create(pthread_tad_t * tad, pthread_t *thread_id, 
  88.   pthread_attr_t *attr, void * (*routine)(), void * arg)
  89. {
  90. #ifndef PTHREAD_KERNEL
  91. struct tad_start tad;
  92. #endif
  93. int ret;
  94. pthread_mutex_lock(&tad->mutex);
  95. while (tad->count_max && (tad->count_current > tad->count_max)) 
  96. pthread_cond_wait(&tad->cond, &tad->mutex);
  97. #ifndef PTHREAD_KERNEL
  98. if ((tad_start = malloc(sizeof(struct tad_start))) == NULL) { 
  99. pthread_mutex_unlock(&tad->mutex);
  100. return(ENOMEM);
  101. }
  102. tad_start->routine = routine;
  103. tad_start->arg = arg;
  104. tad_start->tad = tad;
  105. if ((ret = pthread_create(thread_id, attr, 
  106.   pthread_tad_start, tad_start)) == OK) 
  107. tad->count_current++;
  108. pthread_mutex_unlock(&tad->mutex);
  109. #else
  110. tad->routine = routine;
  111. tad->arg = arg;
  112. if (ret = pthread_create(thread_id, attr, pthread_tad_start, tad))
  113. pthread_mutex_unlock(&tad->mutex);
  114. #endif
  115. return(ret);
  116. }
  117. int pthread_tad_wait(pthread_tad_t * tad, unsigned int count)
  118. {
  119. if ((tad->count_max) && (tad->count_max < count)) {
  120. return(EINVAL);
  121. }
  122. pthread_mutex_lock(&tad->mutex);
  123. while (tad->count_current > count) 
  124. pthread_cond_wait(&tad->cond, &tad->mutex);
  125. pthread_mutex_unlock(&tad->mutex);
  126. return(OK);
  127. }
  128. int pthread_tad_init(pthread_tad_t * tad, unsigned int max_count) 
  129. {
  130. int ret;
  131. if ((ret = pthread_mutex_init(&tad->mutex, NULL)) == OK) {
  132. if (ret = pthread_cond_init(&tad->cond, NULL)) {
  133. pthread_mutex_destroy(&tad->mutex);
  134. } else {
  135. tad->count_max = max_count;
  136. tad->count_current = 0;
  137. }
  138. return(ret);
  139. }
  140. /* User is responsible to make sure their are no threads running */
  141. int pthread_tad_destroy(pthread_tad_t * tad) 
  142. {
  143. int ret;
  144. if ((ret = pthread_mutex_destroy(&tad->mutex)) == OK) {
  145. ret = pthread_cond_destroy(&tad->cond);
  146. } else {
  147. pthread_cond_destroy(&tad->cond);
  148. }
  149. tad->count_max = NOTOK;
  150. return(ret);
  151. }