source: trunk/kernel/syscalls/sys_thread_wakeup.c @ 4

Last change on this file since 4 was 1, checked in by alain, 8 years ago

First import

File size: 2.8 KB
Line 
1/*
2 * kern/sys_thread_wakeup.c - wakeup all indicated threads
3 *
4 * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
5 * Copyright (c) 2011,2012 UPMC Sorbonne Universites
6 *
7 * This file is part of ALMOS-kernel.
8 *
9 * ALMOS-kernel is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; version 2.0 of the License.
12 *
13 * ALMOS-kernel is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with ALMOS-kernel; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#include <errno.h>
24#include <kmagics.h>
25#include <cpu.h>
26#include <kdmsg.h>
27#include <cluster.h>
28#include <task.h>
29#include <scheduler.h>
30#include <thread.h>
31
32/*
33 * FIXME: define spinlock_rdlock() so all locking on task->th_lock
34 * becoms rdlock but on join/detach/destroy
35 */
36int sys_thread_wakeup(pthread_t tid, pthread_t *tid_tbl, uint_t count)
37{
38        struct task_s *task;
39        struct thread_s *this;
40        struct thread_s *target;
41        pthread_t tbl[100];
42        void *listner;
43        uint_t event;
44        sint_t i;
45        error_t err;
46
47        this = current_thread;
48        task = this->task;
49        i = -1;
50
51        if(tid_tbl != NULL)
52        {
53                if((NOT_IN_USPACE((uint_t)tid_tbl + (count*sizeof(pthread_t)))) || 
54                   (count == 0) || (count > 100))
55                {
56                        err = -1;
57                        goto fail_tid_tbl;
58                }
59
60                if((err = cpu_copy_from_uspace(&tbl[0], tid_tbl, sizeof(pthread_t*) * count))) 
61                        goto fail_usapce;
62
63                if(tbl[0] != tid)
64                {
65                        err = -2;
66                        goto fail_first_tid;
67                }
68        }
69        else
70        {
71                count = 1;
72                tbl[0] = tid;
73        }
74
75        for(i = 0; i < count; i++)
76        {
77                tid = tbl[i];
78
79                if(tid > task->max_order)
80                {
81                        err = -3;
82                        goto fail_tid;
83                }
84
85                target = task->th_tbl[tid];
86   
87                if((target == NULL) || (target->signature != THREAD_ID))
88                {
89                        err = -4;
90                        goto fail_target;
91                }
92
93                listner = sched_get_listner(target, SCHED_OP_UWAKEUP);
94                event = sched_event_make(target,SCHED_OP_UWAKEUP);
95   
96                if(this->info.isTraced == true)
97                {
98                        printk(INFO,"%s: tid %d --> tid %d [%d][%d]\n", 
99                               __FUNCTION__, 
100                               this->info.order, 
101                               tid, 
102                               cpu_time_stamp(),
103                               i);
104                }
105
106                sched_event_send(listner,event);
107                cpu_wbflush();
108        }
109
110        return 0;
111
112fail_target:
113fail_tid:
114fail_first_tid:
115fail_usapce:
116fail_tid_tbl:
117
118        printk(INFO, "%s: cpu %d, pid %d, tid %x, i %d, count %d, ttid %x, request has failed with err %d [%d]\n",
119               __FUNCTION__,
120               cpu_get_id(),
121               task->pid,
122               this,
123               i,
124               count,
125               tid,
126               err,
127               cpu_time_stamp());
128 
129        this->info.errno = EINVAL;
130        return -1;
131}
Note: See TracBrowser for help on using the repository browser.