1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
5 * Copyright (C) 2008, Eduardo Silva P.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Library General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 #include <sys/epoll.h>
28 #include <sys/syscall.h>
32 #include "conn_switch.h"
34 #include "scheduler.h"
41 /* Register thread information */
42 int mk_sched_register_thread(pthread_t tid
, int efd
)
44 struct sched_list_node
*sr
, *aux
;
46 sr
= mk_mem_malloc_z(sizeof(struct sched_list_node
));
50 sr
->request_handler
= NULL
;
65 sr
->idx
= aux
->idx
+ 1;
72 * Create thread which will be listening
73 * for incomings file descriptors
75 int mk_sched_launch_thread(int max_events
)
80 sched_thread_conf
*thconf
;
81 pthread_mutex_t mutex_wait_register
;
83 /* Creating epoll file descriptor */
84 efd
= mk_epoll_create(max_events
);
91 pthread_mutex_init(&mutex_wait_register
,(pthread_mutexattr_t
*) NULL
);
92 pthread_mutex_lock(&mutex_wait_register
);
94 thconf
= mk_mem_malloc(sizeof(sched_thread_conf
));
95 thconf
->epoll_fd
= efd
;
96 thconf
->max_events
= max_events
;
98 pthread_attr_init(&attr
);
99 pthread_attr_setdetachstate(&attr
, PTHREAD_CREATE_DETACHED
);
100 if(pthread_create(&tid
, &attr
, mk_sched_launch_epoll_loop
,
103 perror("pthread_create");
107 /* Register working thread */
108 mk_sched_register_thread(tid
, efd
);
109 pthread_mutex_unlock(&mutex_wait_register
);
113 /* created thread, all this calls are in the thread context */
114 void *mk_sched_launch_epoll_loop(void *thread_conf
)
116 sched_thread_conf
*thconf
;
117 struct sched_list_node
*thinfo
;
119 /* Avoid SIGPIPE signals */
120 mk_signal_thread_sigpipe_safe();
122 thconf
= thread_conf
;
124 /* Init specific thread cache */
125 mk_cache_thread_init();
127 mk_epoll_calls
*callers
;
128 callers
= mk_epoll_set_callers((void *)mk_conn_switch
,
130 MK_CONN_SWITCH_WRITE
);
132 /* Nasty way to export task id */
134 thinfo
= mk_sched_get_thread_conf();
136 thinfo
= mk_sched_get_thread_conf();
139 /* Glibc doesn't export to user space the gettid() syscall */
140 thinfo
->pid
= syscall(__NR_gettid
);
142 mk_sched_set_thread_poll(thconf
->epoll_fd
);
143 mk_epoll_init(thconf
->epoll_fd
, callers
, thconf
->max_events
);
148 struct request_idx
*mk_sched_get_request_index()
150 return (struct request_idx
*) pthread_getspecific(request_index
);
153 void mk_sched_set_request_index(struct request_idx
*ri
)
155 pthread_setspecific(request_index
, (void *)ri
);
158 void mk_sched_set_thread_poll(int epoll
)
160 pthread_setspecific(epoll_fd
, (void *) epoll
);
163 int mk_sched_get_thread_poll()
165 return (int) pthread_getspecific(epoll_fd
);
168 struct sched_list_node
*mk_sched_get_thread_conf()
170 struct sched_list_node
*node
;
173 current
= pthread_self();
176 if(pthread_equal(node
->tid
, current
) != 0){
187 void mk_sched_update_thread_status(int active
, int closed
)
189 struct sched_list_node
*thnode
;
191 if(config
->cheetah
== VAR_OFF
){
195 thnode
= mk_sched_get_thread_conf();
198 case MK_SCHEDULER_ACTIVE_UP
:
199 thnode
->active_requests
++;
201 case MK_SCHEDULER_ACTIVE_DOWN
:
202 thnode
->active_requests
--;
207 case MK_SCHEDULER_CLOSED_UP
:
208 thnode
->closed_requests
++;
210 case MK_SCHEDULER_CLOSED_DOWN
:
211 thnode
->closed_requests
--;