~ubuntu-branches/debian/wheezy/ion/wheezy

« back to all changes in this revision

Viewing changes to ici/library/platform_sm.c

  • Committer: Package Import Robot
  • Author(s): Leo Iannacone, Leo Iannacone, Alessio Treglia
  • Date: 2012-06-06 15:05:10 UTC
  • mfrom: (1.1.2)
  • Revision ID: package-import@ubuntu.com-20120606150510-8i80bn0vxwojt76n
Tags: 3.0.1~dfsg1-1
[ Leo Iannacone ]
* New upstream release.
* New patch to fix ftbfs onto kfreebsd systems.
* Refreshed old patches.
* Overrides-lintian false positive about hardening flags.

[ Alessio Treglia ]
* New patch to add pthread libs to libbss's linking
* Required debhelper > 9 to enable hardening flags.

Show diffs side-by-side

added added

removed removed

Lines of Context:
496
496
 
497
497
/****************** Argument buffer services **********************************/
498
498
 
499
 
#if defined (VXWORKS) || defined (RTEMS)
 
499
#if defined (VXWORKS) || defined (RTEMS) || defined (bionic)
500
500
 
501
501
#define ARG_BUFFER_CT   256
502
502
#define MAX_ARG_LENGTH  63
1947
1947
        return 0;
1948
1948
}
1949
1949
 
1950
 
void    sm_TaskVarAdd(int *var)
 
1950
void    *sm_TaskVar(void **arg)
1951
1951
{
1952
 
        taskVarAdd(0, var);
 
1952
        static void     *value;
 
1953
 
 
1954
        if (arg != NULL)
 
1955
        {
 
1956
                /*      Set value by dereferencing argument.            */
 
1957
 
 
1958
                value = *arg;
 
1959
                taskVarAdd(0, (int *) &value);
 
1960
        }
 
1961
 
 
1962
        return value;
1953
1963
}
1954
1964
 
1955
1965
void    sm_TaskSuspend()
2059
2069
 
2060
2070
#endif                  /*      End of #ifdef VXWORKS                   */
2061
2071
 
2062
 
#ifdef RTEMS
 
2072
#if (defined(RTEMS) || defined(bionic))
2063
2073
 
2064
2074
/*      Note: the RTEMS API is UNIX-like except that it omits all SVR4
2065
2075
 *      features.  RTEMS uses POSIX semaphores, and its shared-memory
2066
 
 *      mechanism is the same as the one we use for VxWorks.            */
 
2076
 *      mechanism is the same as the one we use for VxWorks.  The same
 
2077
 *      is true of Bionic.                                              */
2067
2078
 
2068
2079
#include <sys/stat.h>
2069
2080
#include <sched.h>
2070
2081
 
2071
 
        /* ---- Task Control services (RTEMS) ------------------------- */
 
2082
        /* ---- Task Control services (POSIX) ------------------------- */
2072
2083
 
2073
 
#ifndef MAX_RTEMS_TASKS
2074
 
#define MAX_RTEMS_TASKS 50
 
2084
#ifndef MAX_POSIX_TASKS
 
2085
#define MAX_POSIX_TASKS 50
2075
2086
#endif
2076
2087
 
2077
2088
typedef struct
2078
2089
{
2079
 
        int             inUse;                  /*      Boolean.        */
 
2090
        int             inUse;          /*      Boolean.                */
2080
2091
        pthread_t       threadId;
2081
 
} IonRtemsTask;
 
2092
        void            *value;         /*      Task variable value.    */
 
2093
} PosixTask;
2082
2094
 
2083
 
static int      _rtemsTasks(int taskId, pthread_t *threadId)
 
2095
static void     *_posixTasks(int *taskId, pthread_t *threadId, void **arg)
2084
2096
{
2085
 
        static IonRtemsTask     tasks[MAX_RTEMS_TASKS];
2086
 
        static int              initialized;    /*      Boolean.        */
 
2097
        static PosixTask        tasks[MAX_POSIX_TASKS];
 
2098
        static int              initialized = 0;/*      Boolean.        */
2087
2099
        static ResourceLock     tasksLock;
2088
2100
        pthread_t               ownThreadId;
2089
2101
        int                     i;
2090
2102
        int                     vacancy;
2091
 
        IonRtemsTask            *task;
 
2103
        PosixTask               *task;
 
2104
        void                    *value;
2092
2105
 
2093
 
        /*      NOTE: the taskId for an IonRtemsTask is 1 more than
 
2106
        /*      NOTE: the taskId for a PosixTask is 1 more than
2094
2107
         *      the index value for that task in the tasks table.
2095
 
         *      That is, taskIds range from 1 through MAX_RTEMS_TASKS
 
2108
         *      That is, taskIds range from 1 through MAX_POSIX_TASKS
2096
2109
         *      and -1 is an invalid task ID signifying "none".         */
2097
2110
 
2098
2111
        if (!initialized)
2100
2113
                memset((char *) tasks, 0, sizeof tasks);
2101
2114
                if (initResourceLock(&tasksLock) < 0)
2102
2115
                {
2103
 
                        putErrmsg("Can't initialize RTEMS tasks table.", NULL);
2104
 
                        return -1;
 
2116
                        putErrmsg("Can't initialize POSIX tasks table.", NULL);
 
2117
                        return NULL;
2105
2118
                }
2106
2119
 
2107
2120
                initialized = 1;
2109
2122
 
2110
2123
        lockResource(&tasksLock);
2111
2124
 
2112
 
        /*      When taskId is 0, processing depends on the value
 
2125
        /*      taskId must never be NULL; it is always needed.         */
 
2126
 
 
2127
        CHKNULL(taskId);
 
2128
 
 
2129
        /*      When *taskId is 0, processing depends on the value
2113
2130
         *      of threadID.  If threadId is NULL, then the task ID
2114
 
         *      of the calling thread is returned (0 if the thread
2115
 
         *      doesn't have an assigned task ID).  Otherwise, the
2116
 
         *      indicated thread is added as a new task and the ID
2117
 
         *      of that task is returned (-1 if the thread could not
2118
 
         *      be assigned a task ID).
 
2131
         *      of the calling thread (0 if the thread doesn't have
 
2132
         *      an assigned task ID) is written into *taskId.
 
2133
         *      Otherwise, the thread identified by *threadId is
 
2134
         *      added as a new task and the ID of that task (-1
 
2135
         *      if the thread could not be assigned a task ID) is
 
2136
         *      written into *taskId.  In either case, NULL is
 
2137
         *      returned.
2119
2138
         *
2120
 
         *      Otherwise, taskId must be in the range 1 through
2121
 
         *      MAX_RTEMS_TASKS inclusive and processing again
 
2139
         *      Otherwise, *taskId must be in the range 1 through
 
2140
         *      MAX_POSIX_TASKS inclusive and processing again
2122
2141
         *      depends on the value of threadId.  If threadId is
2123
2142
         *      NULL then the indicated task ID is unassigned and
2124
2143
         *      is available for reassignment to another thread;
2125
 
         *      the return value is -1.  Otherwise, the thread ID
2126
 
         *      for the indicated task is passed back in *threadId
2127
 
         *      and the task ID is returned.                            */
 
2144
         *      -1 is written into *taskId and NULL is returned.
 
2145
         *      Otherwise:
 
2146
         *
 
2147
         *              The thread ID for the indicated task is
 
2148
         *              written into *threadId.
 
2149
         *
 
2150
         *              If arg is non-NULL, then the task variable
 
2151
         *              value for the indicated task is set to *arg.
 
2152
         *
 
2153
         *              The current value of the indicated task's
 
2154
         *              task variable is returned.                      */
2128
2155
 
2129
 
        if (taskId == 0)
 
2156
        if (*taskId == 0)
2130
2157
        {
2131
2158
                if (threadId == NULL)   /*      Look up own task ID.    */
2132
2159
                {
2133
2160
                        ownThreadId = pthread_self();
2134
 
                        for (i = 0, task = tasks; i < MAX_RTEMS_TASKS;
 
2161
                        for (i = 0, task = tasks; i < MAX_POSIX_TASKS;
2135
2162
                                        i++, task++)
2136
2163
                        {
2137
2164
                                if (task->inUse == 0)
2141
2168
 
2142
2169
                                if (pthread_equal(task->threadId, ownThreadId))
2143
2170
                                {
 
2171
                                        *taskId = i + 1;
2144
2172
                                        unlockResource(&tasksLock);
2145
 
                                        return i + 1;
 
2173
                                        return NULL;
2146
2174
                                }
2147
2175
                        }
2148
2176
 
2149
 
                        /*      No task ID for this thread.             */
 
2177
                        /*      No task ID for this thread; sub-thread
 
2178
                         *      of a task.                              */
2150
2179
 
2151
2180
                        unlockResource(&tasksLock);
2152
 
                        return 0;       /*      Sub-thread of a task.   */
 
2181
                        return NULL;
2153
2182
                }
2154
2183
 
2155
2184
                /*      Assigning a task ID to this thread.             */
2156
2185
 
2157
2186
                vacancy = -1;
2158
 
                for (i = 0, task = tasks; i < MAX_RTEMS_TASKS; i++, task++)
 
2187
                for (i = 0, task = tasks; i < MAX_POSIX_TASKS; i++, task++)
2159
2188
                {
2160
2189
                        if (task->inUse == 0)
2161
2190
                        {
2170
2199
                                {
2171
2200
                                        /*      Already assigned.       */
2172
2201
 
 
2202
                                        *taskId = i + 1;
2173
2203
                                        unlockResource(&tasksLock);
2174
 
                                        return i + 1;
 
2204
                                        return NULL;
2175
2205
                                }
2176
2206
                        }
2177
2207
                }
2179
2209
                if (vacancy == -1)
2180
2210
                {
2181
2211
                        putErrmsg("Can't start another task.", NULL);
 
2212
                        *taskId = -1;
2182
2213
                        unlockResource(&tasksLock);
2183
 
                        return -1;
 
2214
                        return NULL;
2184
2215
                }
2185
2216
 
2186
2217
                task = tasks + vacancy;
2187
2218
                task->inUse = 1;
2188
2219
                task->threadId = *threadId;
 
2220
                task->value = NULL;
 
2221
                *taskId = vacancy + 1;
2189
2222
                unlockResource(&tasksLock);
2190
 
                return vacancy + 1;
 
2223
                return NULL;
2191
2224
        }
2192
2225
 
2193
2226
        /*      Operating on a previously assigned task ID.             */
2194
2227
 
2195
 
        CHKERR(taskId > 0 && taskId <= MAX_RTEMS_TASKS);
2196
 
        task = tasks + (taskId - 1);
 
2228
        CHKNULL((*taskId) > 0 && (*taskId) <= MAX_POSIX_TASKS);
 
2229
        task = tasks + ((*taskId) - 1);
2197
2230
        if (threadId == NULL)   /*      Unassigning this task ID.       */
2198
2231
        {
2199
2232
                if (task->inUse)
2201
2234
                        task->inUse = 0;
2202
2235
                }
2203
2236
 
 
2237
                *taskId = -1;
2204
2238
                unlockResource(&tasksLock);
2205
 
                return -1;
 
2239
                return NULL;
2206
2240
        }
2207
2241
 
2208
 
        /*      Just looking up the thread ID for this task ID.         */
 
2242
        /*      Just looking up the thread ID for this task ID and/or
 
2243
         *      operating on task variable.                             */
2209
2244
 
2210
2245
        if (task->inUse == 0)   /*      Invalid task ID.                */
2211
2246
        {
 
2247
                *taskId = -1;
2212
2248
                unlockResource(&tasksLock);
2213
 
                return -1;
 
2249
                return NULL;
2214
2250
        }
2215
2251
 
2216
2252
        *threadId = task->threadId;
 
2253
        if (arg)
 
2254
        {
 
2255
                task->value = *arg;
 
2256
        }
 
2257
 
 
2258
        value = task->value;
2217
2259
        unlockResource(&tasksLock);
2218
 
        return taskId;
 
2260
        return value;
2219
2261
}
2220
2262
 
2221
2263
int     sm_TaskIdSelf()
2222
2264
{
2223
 
        int             taskId = _rtemsTasks(0, NULL);
 
2265
        int             taskId = 0;
2224
2266
        pthread_t       threadId;
2225
2267
 
 
2268
        oK(_posixTasks(&taskId, NULL, NULL));
2226
2269
        if (taskId > 0)
2227
2270
        {
2228
2271
                return taskId;
2232
2275
         *      an opportunity to register the thread as a task.        */
2233
2276
 
2234
2277
        sm_TaskYield();
2235
 
        taskId = _rtemsTasks(0, NULL);
 
2278
        oK(_posixTasks(&taskId, NULL, NULL));
2236
2279
        if (taskId > 0)
2237
2280
        {
2238
2281
                return taskId;
2242
2285
         *      It needs to register itself as a task.                  */
2243
2286
 
2244
2287
        threadId = pthread_self();
2245
 
        return _rtemsTasks(0, &threadId);
 
2288
        oK(_posixTasks(&taskId, &threadId, NULL));
 
2289
        return taskId;
2246
2290
}
2247
2291
 
2248
2292
int     sm_TaskExists(int taskId)
2249
2293
{
2250
2294
        pthread_t       threadId;
2251
2295
 
2252
 
        if (_rtemsTasks(taskId, &threadId) != taskId)
 
2296
        oK(_posixTasks(&taskId, &threadId, NULL));
 
2297
        if (taskId < 0)
2253
2298
        {
2254
2299
                return 0;               /*      No such task.           */
2255
2300
        }
2268
2313
        return 0;       /*      No such thread, or some other failure.  */
2269
2314
}
2270
2315
 
2271
 
void    sm_TaskVarAdd(int *var)
 
2316
void    *sm_TaskVar(void **arg)
2272
2317
{
2273
 
        oK(rtems_task_variable_add(rtems_task_self(), (void **) var, NULL));
 
2318
        int             taskId = sm_TaskIdSelf();
 
2319
        pthread_t       threadId;
 
2320
 
 
2321
        return _posixTasks(&taskId, &threadId, arg);
2274
2322
}
2275
2323
 
2276
2324
void    sm_TaskSuspend()
2307
2355
        int     arg10;
2308
2356
} SpawnParms;
2309
2357
 
2310
 
static void     *rtemsDriverThread(void *parm)
 
2358
#ifdef bionic
 
2359
static void     posixTaskExit(int sig)
 
2360
{
 
2361
        pthread_exit(0);
 
2362
}
 
2363
 
 
2364
void    pthread_cancel(pthread_t threadId)
 
2365
{
 
2366
        /*      NOTE that this is NOT a faithful implementation of
 
2367
         *      pthread_cancel(); there is no support for deferred
 
2368
         *      thread cancellation in Bionic (the Android subset
 
2369
         *      of Linux).  It's just a code simplification, solely
 
2370
         *      for the express, limited purpose of shutting down a
 
2371
         *      task immediately, under the highly constrained
 
2372
         *      circumstances defined by sm_TaskSpawn, sm_TaskDelete,
 
2373
         *      and sm_Abort, below.                                    */
 
2374
 
 
2375
        oK(pthread_kill(threadId, SIGUSR2));
 
2376
}
 
2377
#endif
 
2378
 
 
2379
static void     *posixDriverThread(void *parm)
2311
2380
{
2312
2381
        SpawnParms      parms;
2313
2382
 
2319
2388
 
2320
2389
        memset((char *) parm, 0, sizeof(SpawnParms));
2321
2390
 
 
2391
#ifdef bionic
 
2392
        /*      Set up SIGUSR2 handler to enable shutdown.              */
 
2393
 
 
2394
        struct sigaction        actions;
 
2395
 
 
2396
        memset((char *) &actions, 0, sizeof actions);
 
2397
        sigemptyset(&actions.sa_mask);
 
2398
        actions.sa_flags = 0;
 
2399
        actions.sa_handler = posixTaskExit;
 
2400
        oK(sigaction(SIGUSR2, &actions, NULL));
 
2401
#endif
2322
2402
        /*      Run main function of thread.                            */
2323
2403
 
2324
2404
        parms.threadMainFunction(parms.arg1, parms.arg2, parms.arg3,
2383
2463
        parms->arg9 = (int) arg9;
2384
2464
        parms->arg10 = (int) arg10;
2385
2465
        sm_ConfigurePthread(&attr, stackSize);
2386
 
        errno = pthread_create(&threadId, &attr, rtemsDriverThread,
 
2466
        errno = pthread_create(&threadId, &attr, posixDriverThread,
2387
2467
                        (void *) parms);
2388
2468
        if (errno)
2389
2469
        {
2391
2471
                return -1;
2392
2472
        }
2393
2473
 
2394
 
        taskId = _rtemsTasks(0, &threadId);
 
2474
        taskId = 0;     /*      Requesting new task ID for thread.      */
 
2475
        oK(_posixTasks(&taskId, &threadId, NULL));
2395
2476
        if (taskId < 0)         /*      Too many tasks running.         */
2396
2477
        {
2397
2478
                if (pthread_kill(threadId, SIGTERM) == 0)
2407
2488
 
2408
2489
void    sm_TaskForget(int taskId)
2409
2490
{
2410
 
        oK(_rtemsTasks(taskId, NULL));
 
2491
        oK(_posixTasks(&taskId, NULL, NULL));
2411
2492
}
2412
2493
 
2413
2494
void    sm_TaskKill(int taskId, int sigNbr)
2414
2495
{
2415
2496
        pthread_t       threadId;
2416
2497
 
2417
 
        if (_rtemsTasks(taskId, &threadId) != taskId)
 
2498
        oK(_posixTasks(&taskId, &threadId, NULL));
 
2499
        if (taskId < 0)
2418
2500
        {
2419
2501
                return;         /*      No such task.                   */
2420
2502
        }
2426
2508
{
2427
2509
        pthread_t       threadId;
2428
2510
 
2429
 
        if (_rtemsTasks(taskId, &threadId) != taskId)
 
2511
        oK(_posixTasks(&taskId, &threadId, NULL));
 
2512
        if (taskId < 0)
2430
2513
        {
2431
2514
                return;         /*      No such task.                   */
2432
2515
        }
2436
2519
                oK(pthread_cancel(threadId));
2437
2520
        }
2438
2521
 
2439
 
        oK(_rtemsTasks(taskId, NULL));
 
2522
        oK(_posixTasks(&taskId, NULL, NULL));
2440
2523
}
2441
2524
 
2442
2525
void    sm_Abort()
2460
2543
        sm_TaskDelete(taskId);
2461
2544
}
2462
2545
 
2463
 
#endif                  /*      End of #ifdef RTEMS                     */
 
2546
#endif                  /*      End of #ifdef RTEMS || bionic           */
2464
2547
 
2465
2548
#ifdef mingw
2466
2549
 
2515
2598
        return 1;
2516
2599
}
2517
2600
 
2518
 
void    sm_TaskVarAdd(int *var)
 
2601
void    *sm_TaskVar(void **arg)
2519
2602
{
2520
 
        return; /*      All globals of Windows process are "task vars." */
 
2603
        static void     *value;
 
2604
 
 
2605
        /*      Each Windows process has its own distinct instance
 
2606
         *      of each global variable, so all global variables
 
2607
         *      are automatically "task variables".                     */
 
2608
 
 
2609
        if (arg != NULL)
 
2610
        {
 
2611
                /*      Set value by dereferencing argument.            */
 
2612
 
 
2613
                value = *arg;
 
2614
        }
 
2615
 
 
2616
        return value;
2521
2617
}
2522
2618
 
2523
2619
void    sm_TaskSuspend()
2694
2790
}
2695
2791
#endif                  /*      End of #ifdef mingw                     */
2696
2792
 
2697
 
#if (!defined(VXWORKS) && !defined(RTEMS) && !defined(mingw))
 
2793
#if (!defined(VXWORKS) && !defined(RTEMS) && !defined(mingw) && !defined(bionic))
2698
2794
 
2699
2795
        /* ---- IPC services access control (Unix) -------------------- */
2700
2796
 
2741
2837
        return 1;
2742
2838
}
2743
2839
 
2744
 
void    sm_TaskVarAdd(int *var)
 
2840
void    *sm_TaskVar(void **arg)
2745
2841
{
2746
 
        return; /*      All globals of a UNIX process are "task vars."  */
 
2842
        static void     *value;
 
2843
 
 
2844
        /*      Each UNIX process has its own distinct instance
 
2845
         *      of each global variable, so all global variables
 
2846
         *      are automatically "task variables".                     */
 
2847
 
 
2848
        if (arg != NULL)
 
2849
        {
 
2850
                /*      Set value by dereferencing argument.            */
 
2851
 
 
2852
                value = *arg;
 
2853
        }
 
2854
 
 
2855
        return value;
2747
2856
}
2748
2857
 
2749
2858
void    sm_TaskSuspend()
3014
3123
                putErrmsg("More than 11 args in command.", commandLine);
3015
3124
                return -1;
3016
3125
        }
3017
 
#if defined (VXWORKS) || defined (RTEMS)
 
3126
#if defined (VXWORKS) || defined (RTEMS) || defined (bionic)
3018
3127
        takeIpcLock();
3019
3128
        if (copyArgs(argc, argv) < 0)
3020
3129
        {
3026
3135
        pid = sm_TaskSpawn(argv[0], argv[1], argv[2], argv[3],
3027
3136
                        argv[4], argv[5], argv[6], argv[7], argv[8],
3028
3137
                        argv[9], argv[10], 0, 0);
3029
 
#if defined (VXWORKS) || defined (RTEMS)
 
3138
#if defined (VXWORKS) || defined (RTEMS) || defined (bionic)
3030
3139
        if (pid == -1)
3031
3140
        {
3032
3141
                tagArgBuffers(0);