1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=4:tabstop=4:
4 * Copyright (c) 2004 Cluster File Systems, Inc.
6 * This file is part of Lustre, http://www.lustre.org.
8 * Lustre is free software; you can redistribute it and/or modify it under
9 * the terms of version 2 of the GNU General Public License as published by
10 * the Free Software Foundation. Lustre is distributed in the hope that it
11 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details. You should have received a
14 * copy of the GNU General Public License along with Lustre; if not, write
15 * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
18 * Impletion of winnt curproc routines.
21 #define DEBUG_SUBSYSTEM S_LNET
23 #include <libcfs/libcfs.h>
24 #include <libcfs/kp30.h>
28 * Implementation of cfs_curproc API (see portals/include/libcfs/curproc.h)
32 cfs_task_t this_task =
33 { 0, 0, 0, 0, 0, 0, 0,
34 0, 0, 0, 0, 1, 0, 0, 0, 0,
38 uid_t cfs_curproc_uid(void)
43 gid_t cfs_curproc_gid(void)
48 uid_t cfs_curproc_fsuid(void)
50 return this_task.fsuid;
53 gid_t cfs_curproc_fsgid(void)
55 return this_task.fsgid;
58 pid_t cfs_curproc_pid(void)
60 return cfs_current()->pid;
63 int cfs_curproc_groups_nr(void)
65 return this_task.ngroups;
68 void cfs_curproc_groups_dump(gid_t *array, int size)
70 LASSERT(size <= NGROUPS);
71 size = min_t(int, size, this_task.ngroups);
72 memcpy(array, this_task.groups, size * sizeof(__u32));
75 int cfs_curproc_is_in_groups(gid_t gid)
77 return in_group_p(gid);
80 mode_t cfs_curproc_umask(void)
82 return this_task.umask;
85 char *cfs_curproc_comm(void)
87 return this_task.comm;
90 cfs_kernel_cap_t cfs_curproc_cap_get(void)
92 return this_task.cap_effective;
95 void cfs_curproc_cap_set(cfs_kernel_cap_t cap)
97 this_task.cap_effective = cap;
102 * Implementation of linux task management routines
106 /* global of the task manager structure */
118 PTASK_SLOT task = NULL;
121 task = cfs_mem_cache_alloc(TaskMan.slab, 0);
123 task = cfs_alloc(sizeof(TASK_SLOT), 0);
130 init_task_slot(PTASK_SLOT task)
132 memset(task, 0, sizeof(TASK_SLOT));
133 task->Magic = TASKSLT_MAGIC;
134 task->task = this_task;
135 task->task.pid = (pid_t)PsGetCurrentThreadId();
136 cfs_init_event(&task->Event, TRUE, FALSE);
141 cleanup_task_slot(PTASK_SLOT task)
144 cfs_mem_cache_free(TaskMan.slab, task);
151 * task manager related routines
161 PLIST_ENTRY ListEntry = NULL;
162 PTASK_SLOT TaskSlot = NULL;
164 spin_lock(&(TaskMan.Lock));
166 ListEntry = TaskMan.TaskList.Flink;
168 while (ListEntry != (&(TaskMan.TaskList))) {
170 TaskSlot = CONTAINING_RECORD(ListEntry, TASK_SLOT, Link);
172 if (TaskSlot->Pid == ProcessId && TaskSlot->Tid == ThreadId) {
176 DbgPrint("task_manager_notify: Pid=%xh Tid %xh resued (TaskSlot->Tet = %xh)...\n",
177 ProcessId, ThreadId, TaskSlot->Tet);
180 /* remove the taskslot */
181 RemoveEntryList(&(TaskSlot->Link));
182 TaskMan.NumOfTasks--;
184 /* now free the task slot */
185 cleanup_task_slot(TaskSlot);
189 ListEntry = ListEntry->Flink;
192 spin_unlock(&(TaskMan.Lock));
200 /* initialize the content and magic */
201 memset(&TaskMan, 0, sizeof(TASK_MAN));
202 TaskMan.Magic = TASKMAN_MAGIC;
204 /* initialize the spinlock protection */
205 spin_lock_init(&TaskMan.Lock);
207 /* create slab memory cache */
208 TaskMan.slab = cfs_mem_cache_create(
209 "TSLT", sizeof(TASK_SLOT), 0, 0);
211 /* intialize the list header */
212 InitializeListHead(&(TaskMan.TaskList));
214 /* set the thread creation/destruction notify routine */
215 status = PsSetCreateThreadNotifyRoutine(task_manager_notify);
217 if (!NT_SUCCESS(status)) {
218 cfs_enter_debugger();
225 cleanup_task_manager()
227 PLIST_ENTRY ListEntry = NULL;
228 PTASK_SLOT TaskSlot = NULL;
230 /* we must stay in system since we succeed to register the
231 CreateThreadNotifyRoutine: task_manager_notify */
232 cfs_enter_debugger();
235 /* cleanup all the taskslots attached to the list */
236 spin_lock(&(TaskMan.Lock));
238 while (!IsListEmpty(&(TaskMan.TaskList))) {
240 ListEntry = TaskMan.TaskList.Flink;
241 TaskSlot = CONTAINING_RECORD(ListEntry, TASK_SLOT, Link);
243 RemoveEntryList(ListEntry);
244 cleanup_task_slot(TaskSlot);
247 spin_unlock(&TaskMan.Lock);
249 /* destroy the taskslot cache slab */
250 cfs_mem_cache_destroy(TaskMan.slab);
251 memset(&TaskMan, 0, sizeof(TASK_MAN));
256 * schedule routines (task slot list)
263 HANDLE Pid = PsGetCurrentProcessId();
264 HANDLE Tid = PsGetCurrentThreadId();
265 PETHREAD Tet = PsGetCurrentThread();
267 PLIST_ENTRY ListEntry = NULL;
268 PTASK_SLOT TaskSlot = NULL;
270 spin_lock(&(TaskMan.Lock));
272 ListEntry = TaskMan.TaskList.Flink;
274 while (ListEntry != (&(TaskMan.TaskList))) {
276 TaskSlot = CONTAINING_RECORD(ListEntry, TASK_SLOT, Link);
278 if (TaskSlot->Pid == Pid && TaskSlot->Tid == Tid) {
279 if (TaskSlot->Tet != Tet) {
282 DbgPrint("cfs_current: Pid=%xh Tid %xh Tet = %xh resued (TaskSlot->Tet = %xh)...\n",
283 Pid, Tid, Tet, TaskSlot->Tet);
286 // The old thread was already exit. This must be a
287 // new thread which get the same Tid to the previous.
296 if ((ULONG)TaskSlot->Pid > (ULONG)Pid) {
299 } else if ((ULONG)TaskSlot->Pid == (ULONG)Pid) {
300 if ((ULONG)TaskSlot->Tid > (ULONG)Tid) {
309 ListEntry = ListEntry->Flink;
314 TaskSlot = alloc_task_slot();
317 cfs_enter_debugger();
321 init_task_slot(TaskSlot);
327 if (ListEntry == (&(TaskMan.TaskList))) {
329 // Empty case or the biggest case, put it to the tail.
331 InsertTailList(&(TaskMan.TaskList), &(TaskSlot->Link));
334 // Get a slot and smaller than it's tid, put it just before.
336 InsertHeadList(ListEntry->Blink, &(TaskSlot->Link));
339 TaskMan.NumOfTasks++;
343 // To Check whether he task structures are arranged in the expected order ?
347 PTASK_SLOT Prev = NULL, Curr = NULL;
349 ListEntry = TaskMan.TaskList.Flink;
351 while (ListEntry != (&(TaskMan.TaskList))) {
353 Curr = CONTAINING_RECORD(ListEntry, TASK_SLOT, Link);
354 ListEntry = ListEntry->Flink;
357 if ((ULONG)Prev->Pid > (ULONG)Curr->Pid) {
358 cfs_enter_debugger();
359 } else if ((ULONG)Prev->Pid == (ULONG)Curr->Pid) {
360 if ((ULONG)Prev->Tid > (ULONG)Curr->Tid) {
361 cfs_enter_debugger();
372 spin_unlock(&(TaskMan.Lock));
375 cfs_enter_debugger();
379 return (&(TaskSlot->task));
383 schedule_timeout(int64_t time)
385 cfs_task_t * task = cfs_current();
386 PTASK_SLOT slot = NULL;
389 cfs_enter_debugger();
393 slot = CONTAINING_RECORD(task, TASK_SLOT, task);
394 cfs_assert(slot->Magic == TASKSLT_MAGIC);
396 if (time == MAX_SCHEDULE_TIMEOUT) {
400 return (cfs_wait_event(&(slot->Event), time) != 0);
406 return schedule_timeout(0);
414 PTASK_SLOT slot = NULL;
417 cfs_enter_debugger();
421 slot = CONTAINING_RECORD(task, TASK_SLOT, task);
422 cfs_assert(slot->Magic == TASKSLT_MAGIC);
424 cfs_wake_event(&(slot->Event));
436 cfs_waitlink_init(&link);
437 cfs_waitq_add(waitq, &link);
438 cfs_waitq_wait(&link, CFS_TASK_INTERRUPTIBLE);
439 cfs_waitq_del(waitq, &link);
442 EXPORT_SYMBOL(cfs_curproc_uid);
443 EXPORT_SYMBOL(cfs_curproc_pid);
444 EXPORT_SYMBOL(cfs_curproc_gid);
445 EXPORT_SYMBOL(cfs_curproc_fsuid);
446 EXPORT_SYMBOL(cfs_curproc_fsgid);
447 EXPORT_SYMBOL(cfs_curproc_umask);
448 EXPORT_SYMBOL(cfs_curproc_comm);
449 EXPORT_SYMBOL(cfs_curproc_groups_nr);
450 EXPORT_SYMBOL(cfs_curproc_groups_dump);
451 EXPORT_SYMBOL(cfs_curproc_is_in_groups);
452 EXPORT_SYMBOL(cfs_curproc_cap_get);
453 EXPORT_SYMBOL(cfs_curproc_cap_set);