00001 /* Part of the culibs project, <http://www.eideticdew.org/culibs/>. 00002 * Copyright (C) 2005--2007 Petter Urkedal <urkedal@nbi.dk> 00003 * 00004 * This program is free software: you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation, either version 3 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00016 */ 00017 00018 #ifndef CUFLOW_GWORKQ_H 00019 #define CUFLOW_GWORKQ_H 00020 00021 #include <cuflow/fwd.h> 00022 #include <cuflow/workq.h> 00023 #include <cu/tstate.h> 00024 #include <cu/inherit.h> 00025 #include <cu/thread.h> 00026 #include <stdio.h> 00027 #include <atomic_ops.h> 00028 00029 00030 CU_BEGIN_DECLARATIONS 00031 /*!\defgroup cuflow_gworkq_h cuflow/gworkq.h Global Work Queue 00032 * @{\ingroup cuflow_oldsmp_mod 00033 * 00034 * \deprecated \ref cuflow_sched_h "cuflow/sched.h" provides a simpler and more 00035 * efficient alternative. 00036 * 00037 * The global work queue is a way for threads to co-operate to performed 00038 * scheduled function calls in order of priority and in FIFO order within 00039 * a given priority. 00040 * 00041 * On SMP systems, this can be used to parallelise work by letting threads 00042 * performing low-priority tasks help out the high-priority threads when 00043 * work is available. 00044 * The global work queue can also be useful on non-SMP systems to run 00045 * tasks while waiting for resources to become available. */ 00046 00047 typedef int cuflow_priority_t; 00048 00049 /*!One above the maximum priority. */ 00050 #define cuflow_priority_postmax 16 00051 00052 /*!The priority of realtime tasks like audio and video. */ 00053 #define cuflow_priority_realtime 13 00054 00055 /*!The priority of interacive tasks like GUI or curses dialogs. */ 00056 #define cuflow_priority_interactive 10 00057 00058 /*!The priority of common tasks with no specific need. */ 00059 #define cuflow_priority_normal 7 00060 /* NB! Update cu/tstate.c:cuP_tstate_init_glck if changed. */ 00061 00062 /*!The priority of tasks which are to be run only when there is nothing 00063 * else to do. */ 00064 #define cuflow_priority_background 3 00065 00066 00067 /*!The current priority of the running thread. */ 00068 cuflow_priority_t cuflow_gworkq_current_priority(void); 00069 00070 /*!Set the current static priority of the running thread and return its 00071 * previous priority. 00072 * \pre The current thread must be running on a static-priority queue. */ 00073 cuflow_priority_t cuflow_gworkq_set_static_priority(cuflow_priority_t pri); 00074 00075 /*!Yield the processor to tasks at or above \a priority in the global 00076 * work queue and return true iff some work was done. The selected 00077 * task is the first task of the highest priority non-empty queue. */ 00078 cu_bool_t cuflow_gworkq_yield_at(int priority); 00079 00080 cu_bool_t cuflow_gworkq_yield_at_glck(int priority); 00081 00082 /*!Yield the processor to work above the current priority until there is 00083 * no more such work. Returns true iff some work was done. 00084 * This can be scattered at strategic points in low-priority code to 00085 * give more CPUs to high priority tasks. */ 00086 cu_bool_t cuflow_gworkq_yieldall_prior(void); 00087 00088 /*!Yield the processor to work at or above the current priority until 00089 * there is no more such work. Returns true iff some work was done. */ 00090 cu_bool_t cuflow_gworkq_yieldall_prioreq(void); 00091 00092 void cuflow_gworkq_yield_gcond_glck(void); 00093 00094 /*!Same as \ref cuflow_gworkq_yieldall_prior, except that if no work was done, 00095 * try also to run a single task at the current priority. Returns true iff 00096 * some work was done. This is useful while waiting for resources. */ 00097 cu_bool_t cuflow_gworkq_yield_idle(void); 00098 00099 /*!Schedule \a fn to be called at fixed \a priority. */ 00100 void cuflow_gworkq_sched_at(cuflow_workq_fn_t fn, cuflow_priority_t priority); 00101 00102 /*!Schedule \a fn on the current thread's work queue. If a 00103 * \ref cuflow_gflexq_h "flexible-priority queue" is active for the thread, 00104 * it is used, otherwise a the static-priority queue at the same priority 00105 * as the thread is used. */ 00106 void cuflow_gworkq_sched(cuflow_workq_fn_t fn); 00107 00108 /*!Debug dump of global work queues. */ 00109 void cuflow_gworkq_dump(FILE *out); 00110 00111 extern pthread_mutex_t cuflowP_gworkq_mutex; 00112 extern pthread_cond_t cuflowP_gworkq_cond; 00113 00114 CU_SINLINE void 00115 cuflow_gworkq_lock() 00116 { cu_mutex_lock(&cuflowP_gworkq_mutex); } 00117 00118 CU_SINLINE void 00119 cuflow_gworkq_unlock() 00120 { cu_mutex_unlock(&cuflowP_gworkq_mutex); } 00121 00122 CU_SINLINE void 00123 cuflow_gworkq_broadcast() 00124 { pthread_cond_broadcast(&cuflowP_gworkq_cond); } 00125 00126 /*!@}*/ 00127 CU_END_DECLARATIONS 00128 00129 #endif