]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - ipc/ipcdev.git/blob - qnx/src/ipc3x_dev/tiler/resmgr/tiler/main.c
2a12bae900b91af1dca00fb26c7c7f1de4076696
[ipc/ipcdev.git] / qnx / src / ipc3x_dev / tiler / resmgr / tiler / main.c
1 /*
2  * Copyright (c) 2010, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * *  Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * *  Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * *  Neither the name of Texas Instruments Incorporated 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  * */
33 #include "proto.h"
35 #include <stdarg.h>
36 #include <signal.h>
37 #if defined(TILER_PLATFORM_OMAP4)
38 #include <login.h>
39 #endif
41 #define DENY_ALL                    \
42             PROCMGR_ADN_ROOT        \
43             |PROCMGR_ADN_NONROOT    \
44             |PROCMGR_AOP_DENY       \
45             |PROCMGR_AOP_LOCK
47 static resmgr_connect_funcs_t    connect_funcs;
48 static resmgr_io_funcs_t         io_funcs;
49 static iofunc_mount_t            mattr;
50 static iofunc_funcs_t            ocb_funcs;
51 static iofunc_attr_t             attr;
52 static volatile unsigned done = 0;
54 static int lowmem_limit = 128 * 1024 * 1024;
55 static int lowmem_current = INT_MAX;
56 #if _NTO_VERSION >= 660
57 static int lowmem_id = -1;
58 static int lowmem_pulse_prio = -1;
59 #endif
61 int tiler_devctl(resmgr_context_t *ctp, io_devctl_t *msg, tiler_ocb_t *ocb);
62 int tiler_read(resmgr_context_t *ctp, io_read_t *msg, tiler_ocb_t *ocb);
64 #if _NTO_VERSION >= 660
65 static int
66 tiler_lowmem ( message_context_t *ctp, int code, unsigned flags, void *handle )
67 {
68     lowmem_current = procmgr_value_current(lowmem_id);
69 #if 0
70     slogf(99, 1, "current lowmem is %dM, limit is %dM", lowmem_current/1024/1024, lowmem_limit/1024/1024 );
71 #endif
72     if ( tiler_islowmem() ) {
73         tiler_purge();
74     }
75     return EOK;
76 }
77 #endif
79 int tiler_islowmem(void)
80 {
81     return lowmem_current < lowmem_limit;
82 }
84 int tiler_lowmem_init(dispatch_t *dpp)
85 {
86 #if _NTO_VERSION >= 660
87     int code, coid;
88     struct sigevent ev_lowmem;
90     if((code = pulse_attach(dpp, MSG_FLAG_ALLOC_PULSE, 0, &tiler_lowmem, NULL)) == -1) {
91         perror("tiler: Unable to setup lowmem event");
92         return -1;
93     }
95     if ((coid = message_connect(dpp, MSG_FLAG_SIDE_CHANNEL)) == -1) {
96         perror("tiler: Unable to connect to dpp channel");
97         return -1;
98     }
100     SIGEV_PULSE_INIT(&ev_lowmem, coid, lowmem_pulse_prio, code, 0);
102     lowmem_id = procmgr_value_notify_add(PROCMGR_VALUE_FREE_MEM|PROCMGR_VALUE_TRIGGER_DOWN|PROCMGR_VALUE_TRIGGER_UP, 0, lowmem_limit, &ev_lowmem);
103     if ( lowmem_id == -1 ) {
104         perror("tiler: Unable to register to low memory event");
105         return -1;
106     }
107 #endif
108     return 0;
111 int
112 main(int argc, char *const argv[])
114     /* declare variables we'll be using */
115     resmgr_attr_t        resmgr_attr;
116     dispatch_t           *dpp;
117     int                  id;
118     int                  ret = 0;
119     struct stat          sbuf;
120     thread_pool_attr_t   tattr;
121     thread_pool_t        *tpool;
122     sigset_t             set;
123     int32_t              size = 0;
124     int                  c;
125     char                 *user_parm = NULL;
127     while (1)
128     {
129         c = getopt (argc, argv, "S:L:U:");
130         if (c == -1)
131             break;
133         switch (c)
134         {
135         case 'S':
136             size = strtol (optarg, NULL, 0);
137             break;
138         case 'L':
139             lowmem_limit = atoi(optarg) * 1024 * 1024;
140             break;
141         case 'U':
142             user_parm = optarg;
143             break;
144         default:
145             fprintf (stderr, "Unrecognized argument\n");
146         }
147     }
148     /* Obtain I/O privity */
149     ret = ThreadCtl_r (_NTO_TCTL_IO, 0);
150     if (ret)
151     {
152         fprintf(stderr, "Unable to obtain I/O privity");
153         return EXIT_FAILURE;
154     }
156     /* Only let one tiler run. */
157     if (-1 != stat("/dev/tiler", &sbuf)) {
158         return EXIT_FAILURE;
159     }
161     ret = tiler_init(size);
162     if (ret) {
163         fprintf(stderr, "tiler_init failed with status [%d]", ret);
164         return EXIT_FAILURE;
165     }
167     /* initialize dispatch interface */
168     if((dpp = dispatch_create()) == NULL) {
169         fprintf(stderr,
170                 "%s: Unable to allocate dispatch handle.\n",
171                 argv[0]);
172         return EXIT_FAILURE;
173     }
175     /* Initialize the thread pool */
176     memset (&tattr, 0x00, sizeof (thread_pool_attr_t));
177     tattr.handle = dpp;
178     tattr.context_alloc = dispatch_context_alloc;
179     tattr.context_free = dispatch_context_free;
180     tattr.block_func = dispatch_block;
181     tattr.unblock_func = dispatch_unblock;
182     tattr.handler_func = dispatch_handler;
183     tattr.lo_water = 2;
184     tattr.hi_water = 8;
185     tattr.increment = 1;
186     tattr.maximum = 50;
188     /* initialize resource manager attributes */
189     memset(&resmgr_attr, 0, sizeof resmgr_attr);
190     resmgr_attr.nparts_max = 10;
191     resmgr_attr.msg_max_size = 16384;
192     memset(&mattr, 0, sizeof(iofunc_mount_t));
193     mattr.flags = 0;
194     mattr.conf = IOFUNC_PC_CHOWN_RESTRICTED | IOFUNC_PC_NO_TRUNC | IOFUNC_PC_SYNC_IO;
195     mattr.dev = 0;
196     mattr.blocksize=0;
197     mattr.funcs = &ocb_funcs;
198     memset(&ocb_funcs, 0, sizeof(iofunc_funcs_t));
199     ocb_funcs.nfuncs = _IOFUNC_NFUNCS;
200     ocb_funcs.ocb_calloc = ocb_calloc;
201     ocb_funcs.ocb_free = ocb_free;
202     memset(&io_funcs, 0, sizeof(resmgr_io_funcs_t));
203     iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &connect_funcs, _RESMGR_IO_NFUNCS, &io_funcs);
204     io_funcs.devctl = tiler_devctl;
205     //io_funcs.mmap = tiler_mmap;
206     io_funcs.read = tiler_read;
208     iofunc_attr_init(&attr, S_IFNAM | 0777 , 0, 0);
209     attr.mount = &mattr;
211     if ( ( tpool = thread_pool_create(&tattr,0) ) == NULL )
212         return EXIT_FAILURE;
214     if (-1 != stat("/dev/tiler", &sbuf)) {
215         return EXIT_FAILURE;
216     }
218     /* attach our device name */
219     id = resmgr_attach(
220             dpp,            /* dispatch handle        */
221             &resmgr_attr,   /* resource manager attrs */
222             "/dev/tiler",   /* device name            */
223             _FTYPE_ANY,     /* open type              */
224             0,              /* flags                  */
225             &connect_funcs, /* connect routines       */
226             &io_funcs,      /* I/O routines           */
227             &attr);         /* handle                 */
228     if(id == -1) {
229         fprintf(stderr, "%s: Unable to attach name.\n", argv[0]);
230         return EXIT_FAILURE;
231     }
233     /* Setup low memory purger */
234     tiler_lowmem_init(dpp);
236     /* background the process */
237     procmgr_daemon(0, PROCMGR_DAEMON_NOCLOSE|PROCMGR_DAEMON_NODEVNULL);
238     thread_pool_start( tpool );
240     /* Mask out unecessary signals */
241     sigfillset (&set);
242     sigdelset (&set, SIGINT);
243     sigdelset (&set, SIGTERM);
244     pthread_sigmask (SIG_BLOCK, &set, NULL);
246     /* Wait for one of these signals */
247     sigemptyset (&set);
248     sigaddset (&set, SIGINT);
249     sigaddset (&set, SIGQUIT);
250     sigaddset (&set, SIGTERM);
252 #if (_NTO_VERSION >= 800)
253     /* Relinquish privileges */
254     ret = procmgr_ability(  0,
255                             DENY_ALL | PROCMGR_AID_SPAWN,
256                             DENY_ALL | PROCMGR_AID_FORK,
257                             DENY_ALL | PROCMGR_AID_PROT_EXEC,
258                             PROCMGR_ADN_NONROOT | PROCMGR_AOP_ALLOW | PROCMGR_AID_MEM_PEER,
259                             PROCMGR_ADN_NONROOT | PROCMGR_AOP_ALLOW | PROCMGR_AID_MEM_PHYS,
260                             PROCMGR_ADN_NONROOT | PROCMGR_AOP_ALLOW | PROCMGR_AID_MEM_SPECIAL,
261                             PROCMGR_AID_EOL);
263     if(ret != EOK) {
264         fprintf(stderr, "procmgr_ability failed! errno=%d\n", ret);
265         return EXIT_FAILURE;
266     }
268     /* Drop root privileges */
269     if (user_parm != NULL) {
270         if (set_ids_from_arg(user_parm) < 0) {
271             fprintf(stderr, "unable to set uid/gid - %s\n", strerror(errno));
272             return EXIT_FAILURE;
273         }
274     } else {
275         // become nobody if nothing specified from command line
276         if (setuid(99) != 0) {
277                 fprintf(stderr, "unable to set uid - %s\n", strerror(errno));
278         }
279     }
280 #endif
282     /* Wait for a signal */
283     while (1)
284     {
285         switch (SignalWaitinfo (&set, NULL))
286         {
287             case SIGTERM:
288             case SIGQUIT:
289             case SIGINT:
290                 goto done;
291             default:
292                 break;
293         }
294     }
296 done:
297     /* Received SIGTERM: clean up */
298     resmgr_detach(dpp, id, _RESMGR_DETACH_ALL);
300     tiler_exit();
302     return 0;